Skip to content

Servers and cloud ​

Servers, volumes, networks, firewalls and load balancers. Provider actions stay in the app; tokens edit InfraNest's own records and alerting.

Common tasks

Only in the app: Creating, deleting, resizing and rebuilding servers, and anything else billed by the provider.

How it works in the app: help article.

Scopes: Read with cloud.read or monitoring.read, change with cloud.write. See Tokens and scopes.

Every endpoint below takes a token in the Authorization: Bearer header and answers JSON. Errors use the shared format in Errors. Base address: https://api.infranest.io/api.

Cloud firewalls ​

List firewalls ​

Every cloud firewall InfraNest tracks in the organization, a page at a time (per_page, default 20), ordered by account and name. Each includes the entries a Dynamic IP keeps up to date in it.

GET/organizations/{organization}/cloud-firewalls
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-firewalls" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-firewalls" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-firewalls', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-firewalls",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-firewalls', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-firewalls", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "current_page": 1,
  "data": [
    {
      "id": 6,
      "organization_id": 1,
      "provider": "digitalocean",
      "provider_firewall_id": "fw-6",
      "name": "legacy-vpn",
      "rules": [
        {
          "port": "1194",
          "protocol": "udp",
          "direction": "in",
          "source_ips": [
            "0.0.0.0/0"
          ],
          "description": "OpenVPN"
        }
      ],
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "provider_credential_id": 9,
      "applied_to_count": 0,
      "applied_server_ids": [],
      "delete_protection": false,
      "capabilities": {
        "native_delete_protection": false,
        "server_destroy": true,
        "server_destroy_is_cancellation": false,
        "server_create": true,
        "server_rename": true,
        "console": false,
        "snapshots": true,
        "backups": true,
        "isos": false,
        "rescue": false,
        "placement_groups": false,
        "public_network_toggle": false,
        "scheduled_backups": true,
        "private_networks": true,
        "private_network_attach": false,
        "network_join_on_create": true,
        "network_attach_ip_choice": false,
        "private_network_unfiltered": false,
        "floating_ips": true,
        "networks_creatable": true,
        "network_cidr": true,
        "network_subnets": false,
        "network_routes": false,
        "network_rename": true,
        "network_ip_range_extendable": false,
        "firewalls_creatable": true,
        "firewall_multi_server": true,
        "firewall_renamable": true,
        "firewall_outbound": true,
        "firewall_ipv6": true,
        "firewall_dynamic_ip": true,
        "server_firewall": false,
        "load_balancers_creatable": true,
        "load_balancer_rename": true,
        "load_balancer_algorithm": true,
        "load_balancer_services": true,
        "load_balancer_targets": true,
        "volumes_creatable": true,
        "volume_resize": true,
        "volume_rename": false,
        "volume_native_delete_protection": false,
        "network_native_delete_protection": false,
        "user_data": true,
        "install_flavour": false,
        "images_per_plan": false,
        "metrics": true,
        "metrics_disk_throughput": true,
        "rdns_subnet": false,
        "rdns_address_list": false,
        "reverse_dns": false,
        "snapshot_description": false,
        "snapshot_protection": false
      },
      "sync_halt": null,
      "provider_credential": {
        "id": 9,
        "organization_id": 1,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging",
        "enabled": true,
        "verified_at": "2025-10-15T12:00:00.000000Z",
        "last_synced_at": "2026-01-15T11:48:00.000000Z",
        "reconnect_required_at": null,
        "refused_at": null
      },
      "tags": [],
      "dynamic_ip_targets": []
    },
    {
      "id": 4,
      "organization_id": 1,
      "provider": "digitalocean",
      "provider_firewall_id": "fw-4",
      "name": "staging",
      "rules": [
        {
          "port": "443",
          "protocol": "tcp",
          "direction": "in",
          "source_ips": [
            "0.0.0.0/0"
          ],
          "description": "HTTPS"
        },
        {
          "port": "22",
          "protocol": "tcp",
          "direction": "in",
          "source_ips": [
            "203.0.113.0/24"
          ],
          "description": "SSH from the office"
        }
      ],
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "provider_credential_id": 9,
      "applied_to_count": 2,
      "applied_server_ids": [
        "109",
        "110"
      ],
      "delete_protection": false,
      "capabilities": {
        "native_delete_protection": false,
        "server_destroy": true,
        "server_destroy_is_cancellation": false,
        "server_create": true,
        "server_rename": true,
        "console": false,
        "snapshots": true,
        "backups": true,
        "isos": false,
        "rescue": false,
        "placement_groups": false,
        "public_network_toggle": false,
        "scheduled_backups": true,
        "private_networks": true,
        "private_network_attach": false,
        "network_join_on_create": true,
        "network_attach_ip_choice": false,
        "private_network_unfiltered": false,
        "floating_ips": true,
        "networks_creatable": true,
        "network_cidr": true,
        "network_subnets": false,
        "network_routes": false,
        "network_rename": true,
        "network_ip_range_extendable": false,
        "firewalls_creatable": true,
        "firewall_multi_server": true,
        "firewall_renamable": true,
        "firewall_outbound": true,
        "firewall_ipv6": true,
        "firewall_dynamic_ip": true,
        "server_firewall": false,
        "load_balancers_creatable": true,
        "load_balancer_rename": true,
        "load_balancer_algorithm": true,
        "load_balancer_services": true,
        "load_balancer_targets": true,
        "volumes_creatable": true,
        "volume_resize": true,
        "volume_rename": false,
        "volume_native_delete_protection": false,
        "network_native_delete_protection": false,
        "user_data": true,
        "install_flavour": false,
        "images_per_plan": false,
        "metrics": true,
        "metrics_disk_throughput": true,
        "rdns_subnet": false,
        "rdns_address_list": false,
        "reverse_dns": false,
        "snapshot_description": false,
        "snapshot_protection": false
      },
      "sync_halt": null,
      "provider_credential": {
        "id": 9,
        "organization_id": 1,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging",
        "enabled": true,
        "verified_at": "2025-10-15T12:00:00.000000Z",
        "last_synced_at": "2026-01-15T11:48:00.000000Z",
        "reconnect_required_at": null,
        "refused_at": null
      },
      "tags": [],
      "dynamic_ip_targets": []
    }
  ],
  "first_page_url": "http://localhost/api/organizations/1/cloud-firewalls?page=1",
  "from": 1,
  "last_page": 1,
  "last_page_url": "http://localhost/api/organizations/1/cloud-firewalls?page=1",
  "links": [
    {
      "url": null,
      "label": "&laquo; Previous",
      "page": null,
      "active": false
    },
    {
      "url": "http://localhost/api/organizations/1/cloud-firewalls?page=1",
      "label": "1",
      "page": 1,
      "active": true
    }
  ],
  "next_page_url": null,
  "path": "http://localhost/api/organizations/1/cloud-firewalls",
  "per_page": 20,
  "prev_page_url": null,
  "to": 6,
  "total": 6
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Get a firewall ​

One firewall with its rules, tags, Dynamic IP entries, what its provider allows and the protocols it accepts.

GET/organizations/{organization}/cloud-firewalls/{cloudFirewall}
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudFirewallintegerrequired

The cloud firewall's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-firewalls/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-firewalls/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-firewalls/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-firewalls/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-firewalls/1', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-firewalls/1", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 1,
  "organization_id": 1,
  "provider": "hetzner",
  "provider_firewall_id": "fw-1",
  "name": "web-tier",
  "rules": [
    {
      "port": "443",
      "protocol": "tcp",
      "direction": "in",
      "source_ips": [
        "0.0.0.0/0",
        "::/0"
      ],
      "description": "HTTPS"
    },
    {
      "port": "80",
      "protocol": "tcp",
      "direction": "in",
      "source_ips": [
        "0.0.0.0/0",
        "::/0"
      ],
      "description": "HTTP"
    }
  ],
  "deleted_at": null,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "provider_credential_id": 1,
  "applied_to_count": 4,
  "applied_server_ids": [
    "100",
    "101"
  ],
  "delete_protection": false,
  "sync_halt": null,
  "capabilities": {
    "native_delete_protection": true,
    "server_destroy": true,
    "server_destroy_is_cancellation": false,
    "server_create": true,
    "server_rename": true,
    "console": true,
    "snapshots": true,
    "backups": true,
    "isos": true,
    "rescue": true,
    "placement_groups": true,
    "public_network_toggle": true,
    "scheduled_backups": true,
    "private_networks": true,
    "private_network_attach": true,
    "network_join_on_create": false,
    "network_attach_ip_choice": true,
    "private_network_unfiltered": true,
    "floating_ips": true,
    "networks_creatable": true,
    "network_cidr": true,
    "network_subnets": true,
    "network_routes": true,
    "network_rename": true,
    "network_ip_range_extendable": true,
    "firewalls_creatable": true,
    "firewall_multi_server": true,
    "firewall_renamable": true,
    "firewall_outbound": true,
    "firewall_ipv6": true,
    "firewall_dynamic_ip": true,
    "server_firewall": false,
    "load_balancers_creatable": true,
    "load_balancer_rename": true,
    "load_balancer_algorithm": true,
    "load_balancer_services": true,
    "load_balancer_targets": true,
    "volumes_creatable": true,
    "volume_resize": true,
    "volume_rename": true,
    "volume_native_delete_protection": true,
    "network_native_delete_protection": true,
    "user_data": true,
    "install_flavour": false,
    "images_per_plan": false,
    "metrics": true,
    "metrics_disk_throughput": true,
    "rdns_subnet": true,
    "rdns_address_list": false,
    "reverse_dns": true,
    "snapshot_description": true,
    "snapshot_protection": true
  },
  "firewall_protocols": [
    "tcp",
    "udp"
  ],
  "tags": [],
  "dynamic_ip_targets": [],
  "untracked_sources": [],
  "provider_credential": {
    "id": 1,
    "organization_id": 1,
    "provider": "hetzner",
    "label": "Hetzner — Production",
    "enabled": true,
    "verified_at": "2025-10-15T12:00:00.000000Z",
    "last_synced_at": "2026-01-15T11:48:00.000000Z",
    "reconnect_required_at": null,
    "refused_at": null
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Check a firewall for drift ​

Compares the firewall’s rules in InfraNest with the rules live at the cloud provider and returns drifted with the provider’s rules. When the provider cannot be asked, drifted is false and provider_rules is null.

GET/organizations/{organization}/cloud-firewalls/{cloudFirewall}/drift
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudFirewallintegerrequired

The cloud firewall's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-firewalls/1/drift" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-firewalls/1/drift" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-firewalls/1/drift', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-firewalls/1/drift",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-firewalls/1/drift', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-firewalls/1/drift", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

No success response is recorded for this endpoint yet.

Cloud load balancers ​

List load balancers ​

Every load balancer InfraNest tracks in the organization, a page at a time. Filter with search, running, status, datacenter, tag or credential, and sort with sort and dir.

GET/organizations/{organization}/cloud-load-balancers
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-load-balancers" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-load-balancers" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-load-balancers', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-load-balancers",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-load-balancers', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-load-balancers", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "current_page": 1,
  "data": [
    {
      "id": 3,
      "organization_id": 1,
      "provider": "digitalocean",
      "provider_lb_id": "lb-3",
      "name": "staging-lb",
      "status": "running",
      "load_balancer_type": "lb-small",
      "ipv4": "203.0.113.60",
      "ipv6": "2001:db8::60",
      "datacenter": "ams3",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "provider_credential_id": 9,
      "algorithm": "round_robin",
      "services": [
        {
          "protocol": "https",
          "listen_port": 443,
          "destination_port": 443
        }
      ],
      "targets": [
        {
          "type": "server",
          "server_id": 10
        }
      ],
      "price_monthly": "12.00",
      "price_source": "api",
      "price_currency": "eur",
      "delete_protection": false,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "sync_halt": null,
      "provider_credential": {
        "id": 9,
        "organization_id": 1,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging",
        "enabled": true,
        "verified_at": "2025-10-15T12:00:00.000000Z",
        "last_synced_at": "2026-01-15T11:48:00.000000Z",
        "reconnect_required_at": null,
        "refused_at": null
      },
      "tags": []
    },
    {
      "id": 2,
      "organization_id": 1,
      "provider": "hetzner",
      "provider_lb_id": "lb-2",
      "name": "api-lb",
      "status": "running",
      "load_balancer_type": "lb21",
      "ipv4": "203.0.113.51",
      "ipv6": "2001:db8::51",
      "datacenter": "fsn1-dc14",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "provider_credential_id": 1,
      "algorithm": "least_connections",
      "services": [
        {
          "protocol": "https",
          "listen_port": 443,
          "destination_port": 443
        }
      ],
      "targets": [
        {
          "type": "server",
          "server_id": 3
        },
        {
          "type": "server",
          "server_id": 6
        }
      ],
      "price_monthly": "19.90",
      "price_source": "api",
      "price_currency": "eur",
      "delete_protection": false,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "sync_halt": null,
      "provider_credential": {
        "id": 1,
        "organization_id": 1,
        "provider": "hetzner",
        "label": "Hetzner — Production",
        "enabled": true,
        "verified_at": "2025-10-15T12:00:00.000000Z",
        "last_synced_at": "2026-01-15T11:48:00.000000Z",
        "reconnect_required_at": null,
        "refused_at": null
      },
      "tags": []
    }
  ],
  "first_page_url": "http://localhost/api/organizations/1/cloud-load-balancers?page=1",
  "from": 1,
  "last_page": 1,
  "last_page_url": "http://localhost/api/organizations/1/cloud-load-balancers?page=1",
  "links": [
    {
      "url": null,
      "label": "&laquo; Previous",
      "page": null,
      "active": false
    },
    {
      "url": "http://localhost/api/organizations/1/cloud-load-balancers?page=1",
      "label": "1",
      "page": 1,
      "active": true
    }
  ],
  "next_page_url": null,
  "path": "http://localhost/api/organizations/1/cloud-load-balancers",
  "per_page": 25,
  "prev_page_url": null,
  "to": 3,
  "total": 3,
  "meta": {
    "counts": {
      "total": 3,
      "running": 3
    },
    "integrations": [
      {
        "id": 9,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging"
      },
      {
        "id": 1,
        "provider": "hetzner",
        "label": "Hetzner — Production"
      }
    ],
    "tags": []
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Get a load balancer ​

One load balancer with its tags and what its provider allows.

GET/organizations/{organization}/cloud-load-balancers/{cloudLoadBalancer}
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudLoadBalancerintegerrequired

The cloud load balancer's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-load-balancers/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-load-balancers/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-load-balancers/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-load-balancers/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-load-balancers/1', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-load-balancers/1", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 1,
  "organization_id": 1,
  "provider": "hetzner",
  "provider_lb_id": "lb-1",
  "name": "web-lb",
  "status": "running",
  "load_balancer_type": "lb11",
  "ipv4": "203.0.113.50",
  "ipv6": "2001:db8::50",
  "datacenter": "fsn1-dc14",
  "deleted_at": null,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "provider_credential_id": 1,
  "algorithm": "round_robin",
  "services": [
    {
      "protocol": "https",
      "listen_port": 443,
      "destination_port": 443
    }
  ],
  "targets": [
    {
      "type": "server",
      "server_id": 1
    },
    {
      "type": "server",
      "server_id": 2
    }
  ],
  "price_monthly": "5.39",
  "price_source": "api",
  "price_currency": "eur",
  "delete_protection": false,
  "price_amount": null,
  "billing_interval": "monthly",
  "interval_count": 1,
  "sync_halt": null,
  "capabilities": {
    "native_delete_protection": true,
    "server_destroy": true,
    "server_destroy_is_cancellation": false,
    "server_create": true,
    "server_rename": true,
    "console": true,
    "snapshots": true,
    "backups": true,
    "isos": true,
    "rescue": true,
    "placement_groups": true,
    "public_network_toggle": true,
    "scheduled_backups": true,
    "private_networks": true,
    "private_network_attach": true,
    "network_join_on_create": false,
    "network_attach_ip_choice": true,
    "private_network_unfiltered": true,
    "floating_ips": true,
    "networks_creatable": true,
    "network_cidr": true,
    "network_subnets": true,
    "network_routes": true,
    "network_rename": true,
    "network_ip_range_extendable": true,
    "firewalls_creatable": true,
    "firewall_multi_server": true,
    "firewall_renamable": true,
    "firewall_outbound": true,
    "firewall_ipv6": true,
    "firewall_dynamic_ip": true,
    "server_firewall": false,
    "load_balancers_creatable": true,
    "load_balancer_rename": true,
    "load_balancer_algorithm": true,
    "load_balancer_services": true,
    "load_balancer_targets": true,
    "volumes_creatable": true,
    "volume_resize": true,
    "volume_rename": true,
    "volume_native_delete_protection": true,
    "network_native_delete_protection": true,
    "user_data": true,
    "install_flavour": false,
    "images_per_plan": false,
    "metrics": true,
    "metrics_disk_throughput": true,
    "rdns_subnet": true,
    "rdns_address_list": false,
    "reverse_dns": true,
    "snapshot_description": true,
    "snapshot_protection": true
  },
  "provider_credential": {
    "id": 1,
    "organization_id": 1,
    "provider": "hetzner",
    "label": "Hetzner — Production",
    "enabled": true,
    "verified_at": "2025-10-15T12:00:00.000000Z",
    "last_synced_at": "2026-01-15T11:48:00.000000Z",
    "reconnect_required_at": null,
    "refused_at": null
  },
  "tags": []
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

Cloud networks ​

List networks ​

Every private network InfraNest tracks in the organization, ordered by name, with its tags. Not paginated.

GET/organizations/{organization}/cloud-networks
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-networks" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-networks" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-networks', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-networks",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-networks', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-networks", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "data": [
    {
      "id": 1,
      "organization_id": 1,
      "provider_credential_id": 1,
      "provider": "hetzner",
      "provider_network_id": "net-1",
      "name": "private-backbone",
      "ip_range": "10.0.0.0/16",
      "network_zone": "eu-central",
      "subnets_count": 2,
      "routes_count": 0,
      "servers_count": 6,
      "protection": {
        "delete": false
      },
      "labels": [],
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "subnets": [
        {
          "type": "cloud",
          "gateway": "10.0.0.1",
          "ip_range": "10.0.1.0/24",
          "network_zone": "eu-central"
        },
        {
          "type": "cloud",
          "gateway": "10.0.0.1",
          "ip_range": "10.0.2.0/24",
          "network_zone": "eu-central"
        }
      ],
      "routes": [],
      "servers": [
        "100",
        "101"
      ],
      "delete_protection": false,
      "sync_halt": null,
      "provider_credential": {
        "id": 1,
        "organization_id": 1,
        "provider": "hetzner",
        "label": "Hetzner — Production",
        "enabled": true,
        "verified_at": "2025-10-15T12:00:00.000000Z",
        "last_synced_at": "2026-01-15T11:48:00.000000Z",
        "reconnect_required_at": null,
        "refused_at": null
      },
      "tags": []
    },
    {
      "id": 3,
      "organization_id": 1,
      "provider_credential_id": 9,
      "provider": "digitalocean",
      "provider_network_id": "net-3",
      "name": "staging-vpc",
      "ip_range": "10.10.0.0/20",
      "network_zone": "ams3",
      "subnets_count": 1,
      "routes_count": 0,
      "servers_count": 2,
      "protection": {
        "delete": false
      },
      "labels": [],
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "subnets": [
        {
          "type": "cloud",
          "ip_range": "10.10.0.0/20",
          "network_zone": "ams3"
        }
      ],
      "routes": [],
      "servers": [
        "109",
        "110"
      ],
      "delete_protection": false,
      "sync_halt": null,
      "provider_credential": {
        "id": 9,
        "organization_id": 1,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging",
        "enabled": true,
        "verified_at": "2025-10-15T12:00:00.000000Z",
        "last_synced_at": "2026-01-15T11:48:00.000000Z",
        "reconnect_required_at": null,
        "refused_at": null
      },
      "tags": []
    }
  ]
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Get a network ​

One private network with its tags and what its provider allows.

GET/organizations/{organization}/cloud-networks/{cloudNetwork}
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudNetworkintegerrequired

The cloud network's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-networks/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-networks/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-networks/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-networks/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-networks/1', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-networks/1", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 1,
  "organization_id": 1,
  "provider_credential_id": 1,
  "provider": "hetzner",
  "provider_network_id": "net-1",
  "name": "private-backbone",
  "ip_range": "10.0.0.0/16",
  "network_zone": "eu-central",
  "subnets_count": 2,
  "routes_count": 0,
  "servers_count": 6,
  "protection": {
    "delete": false
  },
  "labels": [],
  "deleted_at": null,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "subnets": [
    {
      "type": "cloud",
      "gateway": "10.0.0.1",
      "ip_range": "10.0.1.0/24",
      "network_zone": "eu-central"
    },
    {
      "type": "cloud",
      "gateway": "10.0.0.1",
      "ip_range": "10.0.2.0/24",
      "network_zone": "eu-central"
    }
  ],
  "routes": [],
  "servers": [
    "100",
    "101"
  ],
  "delete_protection": false,
  "sync_halt": null,
  "provider_credential": {
    "id": 1,
    "organization_id": 1,
    "provider": "hetzner",
    "label": "Hetzner — Production",
    "enabled": true,
    "verified_at": "2025-10-15T12:00:00.000000Z",
    "last_synced_at": "2026-01-15T11:48:00.000000Z",
    "reconnect_required_at": null,
    "refused_at": null
  },
  "tags": [],
  "capabilities": {
    "native_delete_protection": true,
    "server_destroy": true,
    "server_destroy_is_cancellation": false,
    "server_create": true,
    "server_rename": true,
    "console": true,
    "snapshots": true,
    "backups": true,
    "isos": true,
    "rescue": true,
    "placement_groups": true,
    "public_network_toggle": true,
    "scheduled_backups": true,
    "private_networks": true,
    "private_network_attach": true,
    "network_join_on_create": false,
    "network_attach_ip_choice": true,
    "private_network_unfiltered": true,
    "floating_ips": true,
    "networks_creatable": true,
    "network_cidr": true,
    "network_subnets": true,
    "network_routes": true,
    "network_rename": true,
    "network_ip_range_extendable": true,
    "firewalls_creatable": true,
    "firewall_multi_server": true,
    "firewall_renamable": true,
    "firewall_outbound": true,
    "firewall_ipv6": true,
    "firewall_dynamic_ip": true,
    "server_firewall": false,
    "load_balancers_creatable": true,
    "load_balancer_rename": true,
    "load_balancer_algorithm": true,
    "load_balancer_services": true,
    "load_balancer_targets": true,
    "volumes_creatable": true,
    "volume_resize": true,
    "volume_rename": true,
    "volume_native_delete_protection": true,
    "network_native_delete_protection": true,
    "user_data": true,
    "install_flavour": false,
    "images_per_plan": false,
    "metrics": true,
    "metrics_disk_throughput": true,
    "rdns_subnet": true,
    "rdns_address_list": false,
    "reverse_dns": true,
    "snapshot_description": true,
    "snapshot_protection": true
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

Cloud primary IPs ​

List IP addresses ​

The IP addresses across your cloud accounts, with the server each is attached to. Where a provider cannot list addresses directly, the list is built from your servers and misses unattached addresses; those accounts are named in server_derived_credentials.

GET/organizations/{organization}/cloud-primary-ips
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-primary-ips" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-primary-ips" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-primary-ips', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-primary-ips",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-primary-ips', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-primary-ips", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "data": [
    {
      "id": "ip_1",
      "name": "web-01-ipv4",
      "ip": "198.51.100.10",
      "type": "ipv4",
      "server_id": 1,
      "server_name": "web-01",
      "last_server_name": "web-01",
      "unattached": false,
      "dns_ptr": [
        {
          "ip": "198.51.100.10",
          "dns_ptr": "web-01.northwind.cloud"
        }
      ],
      "datacenter": "nbg1-dc3",
      "location_city": "Nuremberg",
      "location_country": "de",
      "protection": {
        "delete": false
      },
      "auto_delete": false,
      "blocked": false,
      "price_monthly": 0.6,
      "price_currency": "eur",
      "price_source": "api",
      "cloud_ip_id": 1,
      "credential_id": 1,
      "credential_label": "Hetzner — Production",
      "provider": "hetzner",
      "source": "provider",
      "capabilities": {
        "native_delete_protection": true,
        "server_destroy": true,
        "server_destroy_is_cancellation": false,
        "server_create": true,
        "server_rename": true,
        "console": true,
        "snapshots": true,
        "backups": true,
        "isos": true,
        "rescue": true,
        "placement_groups": true,
        "public_network_toggle": true,
        "scheduled_backups": true,
        "private_networks": true,
        "private_network_attach": true,
        "network_join_on_create": false,
        "network_attach_ip_choice": true,
        "private_network_unfiltered": true,
        "floating_ips": true,
        "networks_creatable": true,
        "network_cidr": true,
        "network_subnets": true,
        "network_routes": true,
        "network_rename": true,
        "network_ip_range_extendable": true,
        "firewalls_creatable": true,
        "firewall_multi_server": true,
        "firewall_renamable": true,
        "firewall_outbound": true,
        "firewall_ipv6": true,
        "firewall_dynamic_ip": true,
        "server_firewall": false,
        "load_balancers_creatable": true,
        "load_balancer_rename": true,
        "load_balancer_algorithm": true,
        "load_balancer_services": true,
        "load_balancer_targets": true,
        "volumes_creatable": true,
        "volume_resize": true,
        "volume_rename": true,
        "volume_native_delete_protection": true,
        "network_native_delete_protection": true,
        "user_data": true,
        "install_flavour": false,
        "images_per_plan": false,
        "metrics": true,
        "metrics_disk_throughput": true,
        "rdns_subnet": true,
        "rdns_address_list": false,
        "reverse_dns": true,
        "snapshot_description": true,
        "snapshot_protection": true
      }
    },
    {
      "id": "ip_2",
      "name": "web-02-ipv4",
      "ip": "198.51.100.11",
      "type": "ipv4",
      "server_id": 2,
      "server_name": "web-02",
      "last_server_name": "web-02",
      "unattached": false,
      "dns_ptr": [
        {
          "ip": "198.51.100.11",
          "dns_ptr": "web-02.northwind.cloud"
        }
      ],
      "datacenter": "nbg1-dc3",
      "location_city": "Nuremberg",
      "location_country": "de",
      "protection": {
        "delete": false
      },
      "auto_delete": false,
      "blocked": false,
      "price_monthly": 0.6,
      "price_currency": "eur",
      "price_source": "api",
      "cloud_ip_id": 2,
      "credential_id": 1,
      "credential_label": "Hetzner — Production",
      "provider": "hetzner",
      "source": "provider",
      "capabilities": {
        "native_delete_protection": true,
        "server_destroy": true,
        "server_destroy_is_cancellation": false,
        "server_create": true,
        "server_rename": true,
        "console": true,
        "snapshots": true,
        "backups": true,
        "isos": true,
        "rescue": true,
        "placement_groups": true,
        "public_network_toggle": true,
        "scheduled_backups": true,
        "private_networks": true,
        "private_network_attach": true,
        "network_join_on_create": false,
        "network_attach_ip_choice": true,
        "private_network_unfiltered": true,
        "floating_ips": true,
        "networks_creatable": true,
        "network_cidr": true,
        "network_subnets": true,
        "network_routes": true,
        "network_rename": true,
        "network_ip_range_extendable": true,
        "firewalls_creatable": true,
        "firewall_multi_server": true,
        "firewall_renamable": true,
        "firewall_outbound": true,
        "firewall_ipv6": true,
        "firewall_dynamic_ip": true,
        "server_firewall": false,
        "load_balancers_creatable": true,
        "load_balancer_rename": true,
        "load_balancer_algorithm": true,
        "load_balancer_services": true,
        "load_balancer_targets": true,
        "volumes_creatable": true,
        "volume_resize": true,
        "volume_rename": true,
        "volume_native_delete_protection": true,
        "network_native_delete_protection": true,
        "user_data": true,
        "install_flavour": false,
        "images_per_plan": false,
        "metrics": true,
        "metrics_disk_throughput": true,
        "rdns_subnet": true,
        "rdns_address_list": false,
        "reverse_dns": true,
        "snapshot_description": true,
        "snapshot_protection": true
      }
    }
  ],
  "server_derived_credentials": [
    {
      "id": 5,
      "label": "TransIP — Amsterdam",
      "provider": "transip"
    },
    {
      "id": 8,
      "label": "OVHcloud — Beauharnois",
      "provider": "ovh"
    }
  ]
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

Cloud servers ​

List servers ​

Every server InfraNest tracks in the organization, a page at a time, with its provider, status, addresses and tags. Filter with search, status, running, datacenter, tag, credential, provider or tracking=untracked, and sort with sort and dir; self-managed machines are counted in meta but not listed.

GET/organizations/{organization}/cloud-servers
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "current_page": 1,
  "data": [
    {
      "id": 13,
      "organization_id": 1,
      "provider": "digitalocean",
      "provider_server_id": "112",
      "name": "analytics-01",
      "status": "stopped",
      "server_type": "c-4",
      "image": "ubuntu-24-04-x64",
      "ipv4": "192.0.2.80",
      "ipv6": null,
      "datacenter": "nyc3",
      "provisioned_at": "2025-07-25T12:00:00.000000Z",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "meta": {
        "vcpus": 4,
        "ram_gb": 8,
        "disk_gb": 50,
        "price_monthly": "84.00",
        "price_hourly": "0.1151",
        "location_city": "New York",
        "location_country": "US",
        "included_traffic": 6597069766656,
        "outgoing_traffic": 131941395333,
        "incoming_traffic": 65970697667,
        "ipv4_dns_ptr": "analytics-01.northwind.cloud",
        "firewall_enabled": false
      },
      "provider_credential_id": 9,
      "price_monthly": null,
      "price_source": "api",
      "price_currency": null,
      "backup_price_override": null,
      "delete_protection": false,
      "untracked_at": null,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "metrics_source": "provider",
      "agent_health": null,
      "monitoring_enabled": false,
      "monitoring_enabled_at": null,
      "volumes_count": 0,
      "agent_last_seen_at": null,
      "agent_tokens_count": 0,
      "custom_fields": {
        "1": "Data"
      },
      "capabilities": {
        "native_delete_protection": false,
        "server_destroy": true,
        "server_destroy_is_cancellation": false,
        "server_create": true,
        "server_rename": true,
        "console": false,
        "snapshots": true,
        "backups": true,
        "isos": false,
        "rescue": false,
        "placement_groups": false,
        "public_network_toggle": false,
        "scheduled_backups": true,
        "private_networks": true,
        "private_network_attach": false,
        "network_join_on_create": true,
        "network_attach_ip_choice": false,
        "private_network_unfiltered": false,
        "floating_ips": true,
        "networks_creatable": true,
        "network_cidr": true,
        "network_subnets": false,
        "network_routes": false,
        "network_rename": true,
        "network_ip_range_extendable": false,
        "firewalls_creatable": true,
        "firewall_multi_server": true,
        "firewall_renamable": true,
        "firewall_outbound": true,
        "firewall_ipv6": true,
        "firewall_dynamic_ip": true,
        "server_firewall": false,
        "load_balancers_creatable": true,
        "load_balancer_rename": true,
        "load_balancer_algorithm": true,
        "load_balancer_services": true,
        "load_balancer_targets": true,
        "volumes_creatable": true,
        "volume_resize": true,
        "volume_rename": false,
        "volume_native_delete_protection": false,
        "network_native_delete_protection": false,
        "user_data": true,
        "install_flavour": false,
        "images_per_plan": false,
        "metrics": true,
        "metrics_disk_throughput": true,
        "rdns_subnet": false,
        "rdns_address_list": false,
        "reverse_dns": false,
        "snapshot_description": false,
        "snapshot_protection": false
      },
      "hardware": {
        "vcpus": 4,
        "ram_gb": 8,
        "disk_gb": 50,
        "plan": {
          "vcpus": 4,
          "ram_gb": 8,
          "disk_gb": 50
        },
        "machine": {
          "vcpus": null,
          "ram_gb": null,
          "disk_gb": null
        },
        "mismatch": [],
        "disk_unallocated": false
      },
      "live_status": "stopped",
      "sync_halt": null,
      "provider_credential": {
        "id": 9,
        "organization_id": 1,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging",
        "enabled": true,
        "verified_at": "2025-10-15T12:00:00.000000Z",
        "last_synced_at": "2026-01-15T11:48:00.000000Z",
        "reconnect_required_at": null,
        "refused_at": null
      },
      "tags": [
        {
          "id": 2,
          "name": "Staging",
          "color": "#f59e0b",
          "pivot": {
            "taggable_type": "App\\Models\\CloudServer",
            "taggable_id": 13,
            "tag_id": 2
          }
        }
      ]
    },
    {
      "id": 12,
      "organization_id": 1,
      "provider": "digitalocean",
      "provider_server_id": "111",
      "name": "queue-01",
      "status": "running",
      "server_type": "s-4vcpu-8gb",
      "image": "ubuntu-24-04-x64",
      "ipv4": "192.0.2.40",
      "ipv6": "2001:db8:3:d0::a22:1/64",
      "datacenter": "fra1",
      "provisioned_at": "2025-08-06T12:00:00.000000Z",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "meta": {
        "vcpus": 4,
        "ram_gb": 8,
        "disk_gb": 160,
        "price_monthly": "48.00",
        "price_hourly": "0.0658",
        "location_city": "Frankfurt",
        "location_country": "DE",
        "included_traffic": 5497558138880,
        "outgoing_traffic": 1044536046387,
        "incoming_traffic": 384829069722,
        "ipv4_dns_ptr": "queue-01.northwind.cloud",
        "firewall_enabled": false
      },
      "provider_credential_id": 9,
      "price_monthly": null,
      "price_source": "api",
      "price_currency": null,
      "backup_price_override": null,
      "delete_protection": false,
      "untracked_at": null,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "metrics_source": "agent",
      "agent_health": null,
      "monitoring_enabled": true,
      "monitoring_enabled_at": null,
      "volumes_count": 0,
      "agent_last_seen_at": null,
      "agent_tokens_count": 0,
      "custom_fields": {
        "1": "Platform"
      },
      "capabilities": {
        "native_delete_protection": false,
        "server_destroy": true,
        "server_destroy_is_cancellation": false,
        "server_create": true,
        "server_rename": true,
        "console": false,
        "snapshots": true,
        "backups": true,
        "isos": false,
        "rescue": false,
        "placement_groups": false,
        "public_network_toggle": false,
        "scheduled_backups": true,
        "private_networks": true,
        "private_network_attach": false,
        "network_join_on_create": true,
        "network_attach_ip_choice": false,
        "private_network_unfiltered": false,
        "floating_ips": true,
        "networks_creatable": true,
        "network_cidr": true,
        "network_subnets": false,
        "network_routes": false,
        "network_rename": true,
        "network_ip_range_extendable": false,
        "firewalls_creatable": true,
        "firewall_multi_server": true,
        "firewall_renamable": true,
        "firewall_outbound": true,
        "firewall_ipv6": true,
        "firewall_dynamic_ip": true,
        "server_firewall": false,
        "load_balancers_creatable": true,
        "load_balancer_rename": true,
        "load_balancer_algorithm": true,
        "load_balancer_services": true,
        "load_balancer_targets": true,
        "volumes_creatable": true,
        "volume_resize": true,
        "volume_rename": false,
        "volume_native_delete_protection": false,
        "network_native_delete_protection": false,
        "user_data": true,
        "install_flavour": false,
        "images_per_plan": false,
        "metrics": true,
        "metrics_disk_throughput": true,
        "rdns_subnet": false,
        "rdns_address_list": false,
        "reverse_dns": false,
        "snapshot_description": false,
        "snapshot_protection": false
      },
      "hardware": {
        "vcpus": 4,
        "ram_gb": 8,
        "disk_gb": 160,
        "plan": {
          "vcpus": 4,
          "ram_gb": 8,
          "disk_gb": 160
        },
        "machine": {
          "vcpus": null,
          "ram_gb": null,
          "disk_gb": null
        },
        "mismatch": [],
        "disk_unallocated": false
      },
      "live_status": "running",
      "sync_halt": null,
      "provider_credential": {
        "id": 9,
        "organization_id": 1,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging",
        "enabled": true,
        "verified_at": "2025-10-15T12:00:00.000000Z",
        "last_synced_at": "2026-01-15T11:48:00.000000Z",
        "reconnect_required_at": null,
        "refused_at": null
      },
      "tags": [
        {
          "id": 1,
          "name": "Production",
          "color": "#ef4444",
          "pivot": {
            "taggable_type": "App\\Models\\CloudServer",
            "taggable_id": 12,
            "tag_id": 1
          }
        }
      ]
    }
  ],
  "first_page_url": "http://localhost/api/organizations/1/cloud-servers?page=1",
  "from": 1,
  "last_page": 1,
  "last_page_url": "http://localhost/api/organizations/1/cloud-servers?page=1",
  "links": [
    {
      "url": null,
      "label": "&laquo; Previous",
      "page": null,
      "active": false
    },
    {
      "url": "http://localhost/api/organizations/1/cloud-servers?page=1",
      "label": "1",
      "page": 1,
      "active": true
    }
  ],
  "next_page_url": null,
  "path": "http://localhost/api/organizations/1/cloud-servers",
  "per_page": 25,
  "prev_page_url": null,
  "to": 14,
  "total": 14,
  "meta": {
    "locked_ids": [],
    "counts": {
      "total": 14,
      "running": 12,
      "untracked": 0,
      "self_managed": 0
    },
    "integrations": [
      {
        "id": 9,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging",
        "capabilities": {
          "native_delete_protection": false,
          "server_destroy": true,
          "server_destroy_is_cancellation": false,
          "server_create": true,
          "server_rename": true,
          "console": false,
          "snapshots": true,
          "backups": true,
          "isos": false,
          "rescue": false,
          "placement_groups": false,
          "public_network_toggle": false,
          "scheduled_backups": true,
          "private_networks": true,
          "private_network_attach": false,
          "network_join_on_create": true,
          "network_attach_ip_choice": false,
          "private_network_unfiltered": false,
          "floating_ips": true,
          "networks_creatable": true,
          "network_cidr": true,
          "network_subnets": false,
          "network_routes": false,
          "network_rename": true,
          "network_ip_range_extendable": false,
          "firewalls_creatable": true,
          "firewall_multi_server": true,
          "firewall_renamable": true,
          "firewall_outbound": true,
          "firewall_ipv6": true,
          "firewall_dynamic_ip": true,
          "server_firewall": false,
          "load_balancers_creatable": true,
          "load_balancer_rename": true,
          "load_balancer_algorithm": true,
          "load_balancer_services": true,
          "load_balancer_targets": true,
          "volumes_creatable": true,
          "volume_resize": true,
          "volume_rename": false,
          "volume_native_delete_protection": false,
          "network_native_delete_protection": false,
          "user_data": true,
          "install_flavour": false,
          "images_per_plan": false,
          "metrics": true,
          "metrics_disk_throughput": true,
          "rdns_subnet": false,
          "rdns_address_list": false,
          "reverse_dns": false,
          "snapshot_description": false,
          "snapshot_protection": false
        }
      },
      {
        "id": 1,
        "provider": "hetzner",
        "label": "Hetzner — Production",
        "capabilities": {
          "native_delete_protection": true,
          "server_destroy": true,
          "server_destroy_is_cancellation": false,
          "server_create": true,
          "server_rename": true,
          "console": true,
          "snapshots": true,
          "backups": true,
          "isos": true,
          "rescue": true,
          "placement_groups": true,
          "public_network_toggle": true,
          "scheduled_backups": true,
          "private_networks": true,
          "private_network_attach": true,
          "network_join_on_create": false,
          "network_attach_ip_choice": true,
          "private_network_unfiltered": true,
          "floating_ips": true,
          "networks_creatable": true,
          "network_cidr": true,
          "network_subnets": true,
          "network_routes": true,
          "network_rename": true,
          "network_ip_range_extendable": true,
          "firewalls_creatable": true,
          "firewall_multi_server": true,
          "firewall_renamable": true,
          "firewall_outbound": true,
          "firewall_ipv6": true,
          "firewall_dynamic_ip": true,
          "server_firewall": false,
          "load_balancers_creatable": true,
          "load_balancer_rename": true,
          "load_balancer_algorithm": true,
          "load_balancer_services": true,
          "load_balancer_targets": true,
          "volumes_creatable": true,
          "volume_resize": true,
          "volume_rename": true,
          "volume_native_delete_protection": true,
          "network_native_delete_protection": true,
          "user_data": true,
          "install_flavour": false,
          "images_per_plan": false,
          "metrics": true,
          "metrics_disk_throughput": true,
          "rdns_subnet": true,
          "rdns_address_list": false,
          "reverse_dns": true,
          "snapshot_description": true,
          "snapshot_protection": true
        }
      }
    ],
    "tags": [
      {
        "id": 3,
        "name": "Customer-facing",
        "color": "#3b82f6"
      },
      {
        "id": 6,
        "name": "Northwind Platform",
        "color": "#14b8a6"
      }
    ],
    "custom_fields": [
      {
        "id": 1,
        "key": "cost_centre",
        "label": "Cost centre",
        "type": "select",
        "options": [
          "Platform",
          "Marketing"
        ]
      }
    ]
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Get a server ​

One server with its volumes, tags, cost breakdown and what its provider lets InfraNest do with it. Also says whether it can be renamed and whether its monitoring agent’s readings are being refused.

GET/organizations/{organization}/cloud-servers/{cloudServer}
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 1,
  "organization_id": 1,
  "provider": "hetzner",
  "provider_server_id": "100",
  "name": "web-01",
  "status": "running",
  "server_type": "cpx31",
  "image": "ubuntu-24.04",
  "ipv4": "198.51.100.10",
  "ipv6": "2001:db8:1c1e:5a10::/64",
  "datacenter": "nbg1-dc3",
  "provisioned_at": "2025-12-16T12:00:00.000000Z",
  "deleted_at": null,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "meta": {
    "vcpus": 4,
    "ram_gb": 8,
    "disk_gb": 160,
    "price_monthly": "15.90",
    "price_hourly": "0.0218",
    "location_city": "Nuremberg",
    "location_country": "DE",
    "included_traffic": 21990232555520,
    "outgoing_traffic": 6816972092211,
    "incoming_traffic": 1979120929997,
    "ipv4_dns_ptr": "web-01.northwind.cloud",
    "firewall_enabled": false,
    "backup_window": "22-02"
  },
  "provider_credential_id": 1,
  "price_monthly": null,
  "price_source": "api",
  "price_currency": null,
  "backup_price_override": null,
  "delete_protection": true,
  "untracked_at": null,
  "price_amount": null,
  "billing_interval": "monthly",
  "interval_count": 1,
  "metrics_source": "agent",
  "agent_health": null,
  "monitoring_enabled": true,
  "monitoring_enabled_at": null,
  "volumes_count": 1,
  "hardware": {
    "vcpus": 4,
    "ram_gb": 8,
    "disk_gb": 160,
    "plan": {
      "vcpus": 4,
      "ram_gb": 8,
      "disk_gb": 160
    },
    "machine": {
      "vcpus": null,
      "ram_gb": null,
      "disk_gb": null
    },
    "mismatch": [],
    "disk_unallocated": false
  },
  "live_status": "running",
  "sync_halt": null,
  "volumes": [
    {
      "id": 3,
      "organization_id": 1,
      "cloud_server_id": 1,
      "provider": "hetzner",
      "provider_volume_id": "vol-3",
      "name": "uploads",
      "size_gb": 250,
      "status": "attached",
      "datacenter": "nbg1-dc3",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "provider_credential_id": 1,
      "price_monthly": "12.00",
      "price_source": "api",
      "price_currency": "eur",
      "delete_protection": false,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "native_delete_protection": false,
      "sync_halt": null
    }
  ],
  "tags": [
    {
      "id": 3,
      "name": "Customer-facing",
      "color": "#3b82f6",
      "pivot": {
        "taggable_type": "App\\Models\\CloudServer",
        "taggable_id": 1,
        "tag_id": 3
      }
    },
    {
      "id": 5,
      "name": "Northwind Retail",
      "color": "#0ea5e9",
      "pivot": {
        "taggable_type": "App\\Models\\CloudServer",
        "taggable_id": 1,
        "tag_id": 5
      }
    }
  ],
  "provider_credential": {
    "id": 1,
    "organization_id": 1,
    "provider": "hetzner",
    "label": "Hetzner — Production",
    "enabled": true,
    "verified_at": "2025-10-15T12:00:00.000000Z",
    "last_synced_at": "2026-01-15T11:48:00.000000Z",
    "reconnect_required_at": null,
    "refused_at": null
  },
  "cost": {
    "base": 15.9,
    "currency": "EUR",
    "source": "api",
    "extras": [
      {
        "key": "backups",
        "amount": 3.18,
        "source": "computed",
        "own": true
      },
      {
        "key": "volume",
        "label": "uploads",
        "amount": 12,
        "source": "api",
        "own": false
      }
    ],
    "total": 31.75
  },
  "capabilities": {
    "native_delete_protection": true,
    "server_destroy": true,
    "server_destroy_is_cancellation": false,
    "server_create": true,
    "server_rename": true,
    "console": true,
    "snapshots": true,
    "backups": true,
    "isos": true,
    "rescue": true,
    "placement_groups": true,
    "public_network_toggle": true,
    "scheduled_backups": true,
    "private_networks": true,
    "private_network_attach": true,
    "network_join_on_create": false,
    "network_attach_ip_choice": true,
    "private_network_unfiltered": true,
    "floating_ips": true,
    "networks_creatable": true,
    "network_cidr": true,
    "network_subnets": true,
    "network_routes": true,
    "network_rename": true,
    "network_ip_range_extendable": true,
    "firewalls_creatable": true,
    "firewall_multi_server": true,
    "firewall_renamable": true,
    "firewall_outbound": true,
    "firewall_ipv6": true,
    "firewall_dynamic_ip": true,
    "server_firewall": false,
    "load_balancers_creatable": true,
    "load_balancer_rename": true,
    "load_balancer_algorithm": true,
    "load_balancer_services": true,
    "load_balancer_targets": true,
    "volumes_creatable": true,
    "volume_resize": true,
    "volume_rename": true,
    "volume_native_delete_protection": true,
    "network_native_delete_protection": true,
    "user_data": true,
    "install_flavour": false,
    "images_per_plan": false,
    "metrics": true,
    "metrics_disk_throughput": true,
    "rdns_subnet": true,
    "rdns_address_list": false,
    "reverse_dns": true,
    "snapshot_description": true,
    "snapshot_protection": true
  },
  "capability_blockers": [],
  "rename_refusal": null,
  "agent_silent_after_seconds": 300,
  "agent_refusal": null,
  "uptime_seconds": 3542400
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Update a server ​

Changes a server’s name, city, country or tags; only the fields you send change. A new name is sent to the cloud provider first and refused when the provider cannot rename servers, while the provider’s own facts (addresses, type, status) can only be edited on a self-managed server.

PUT/organizations/{organization}/cloud-servers/{cloudServer}
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Bodyapplication/json
providerstring, nullableoptional
provider_server_idstring, nullableoptional

Must not be greater than 255 characters.

namestringoptional

Must not be greater than 255 characters.

statusstringoptional

One of: running, stopped, starting, stopping, rebuilding, migrating, provisioning, error, unknown

server_typestring, nullableoptional

Must not be greater than 100 characters.

imagestring, nullableoptional

Must not be greater than 100 characters.

ipv4string, nullableoptional

Must not be greater than 45 characters.

ipv6string, nullableoptional

Must not be greater than 45 characters.

datacenterstring, nullableoptional

Must not be greater than 100 characters.

provisioned_atstring, nullableoptional

Must be a valid date.

metaobjectoptional

Request

sh
curl -X PUT "https://api.infranest.io/api/organizations/42/cloud-servers/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"office-nas-01"}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "name": "office-nas-01"
}
'@
Invoke-RestMethod -Method Put -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1" -Headers $headers -ContentType "application/json" -Body $body
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://api.infranest.io/api/organizations/42/cloud-servers/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'name' => 'office-nas-01',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.put(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "name": "office-nas-01",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "office-nas-01"
  }),
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	req, err := http.NewRequest("PUT", "https://api.infranest.io/api/organizations/42/cloud-servers/1", strings.NewReader(`{"name":"office-nas-01"}`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 15,
  "organization_id": 1,
  "provider": "self_managed",
  "provider_server_id": null,
  "name": "office-nas-01",
  "status": "running",
  "server_type": null,
  "image": null,
  "ipv4": "192.0.2.40",
  "ipv6": null,
  "datacenter": null,
  "provisioned_at": null,
  "deleted_at": null,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "meta": null,
  "provider_credential_id": null,
  "price_monthly": null,
  "price_source": "api",
  "price_currency": null,
  "backup_price_override": null,
  "delete_protection": false,
  "untracked_at": null,
  "price_amount": null,
  "billing_interval": "monthly",
  "interval_count": 1,
  "metrics_source": "provider",
  "agent_health": null,
  "monitoring_enabled": false,
  "monitoring_enabled_at": null,
  "volumes_count": 0,
  "hardware": {
    "vcpus": null,
    "ram_gb": null,
    "disk_gb": null,
    "plan": {
      "vcpus": null,
      "ram_gb": null,
      "disk_gb": null
    },
    "machine": {
      "vcpus": null,
      "ram_gb": null,
      "disk_gb": null
    },
    "mismatch": [],
    "disk_unallocated": false
  },
  "live_status": "running",
  "sync_halt": null,
  "volumes": [],
  "tags": [],
  "provider_credential": null,
  "cost": {
    "base": null,
    "currency": "EUR",
    "source": "api",
    "extras": [],
    "total": null
  },
  "capabilities": [],
  "capability_blockers": [],
  "rename_refusal": null,
  "agent_silent_after_seconds": 300,
  "agent_refusal": null,
  "uptime_seconds": null
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The provider field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "provider": [
      "The provider field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
422 validation_failed
429 rate_limited


List a server’s add-ons ​

The add-ons the cloud provider reports for this server, asked live. Empty when the provider account’s access does not cover it; refused when the server has no linked provider account.

GET/organizations/{organization}/cloud-servers/{cloudServer}/addons
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/addons" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/addons" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/addons', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/addons",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/addons', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/addons", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

No success response is recorded for this endpoint yet.


Get what refers to a server’s addresses ​

The DNS records, firewall rules and monitors that name this server’s IPv4 or IPv6 address, with a total. Also lists the other servers a DNS record could be moved to, which is useful before deleting the server.

GET/organizations/{organization}/cloud-servers/{cloudServer}/address-references
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/address-references" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/address-references" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/address-references', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/address-references",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/address-references', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/address-references", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "addresses": [
    "198.51.100.10",
    "2001:db8:1c1e:5a10::/64"
  ],
  "dns_records": [
    {
      "zone_id": 1,
      "zone_name": "northwind.com",
      "record_id": 1,
      "name": "northwind.com",
      "fqdn": "northwind.com",
      "type": "A",
      "value": "198.51.100.10",
      "writable": false,
      "aliases": [
        {
          "zone_id": 1,
          "record_id": 3,
          "fqdn": "api.northwind.com"
        }
      ]
    },
    {
      "zone_id": 1,
      "zone_name": "northwind.com",
      "record_id": 2,
      "name": "www",
      "fqdn": "www.northwind.com",
      "type": "A",
      "value": "198.51.100.10",
      "writable": false,
      "aliases": []
    }
  ],
  "firewall_rules": [],
  "monitors": [],
  "total": 21,
  "move_targets": [
    {
      "id": 13,
      "name": "analytics-01",
      "ipv4": "192.0.2.80",
      "ipv6": null,
      "ipv6_basis": null
    },
    {
      "id": 3,
      "name": "api-01",
      "ipv4": "198.51.100.20",
      "ipv6": "2001:db8:1c1e:5a20::1",
      "ipv6_basis": "default"
    }
  ]
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Get the latest monitoring agent release ​

The current release of the InfraNest monitoring agent with its checksums, the install script URLs and the address the agent should report to. The answer is the same for every server.

GET/organizations/{organization}/cloud-servers/{cloudServer}/agent-release
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-release" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-release" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-release', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-release",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-release', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-release", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "version": null,
  "published_at": null,
  "install_sh_sha256": null,
  "install_ps1_sha256": null,
  "repo": "InfraNest-Infrastructure-Organized/infranest-agent",
  "install_sh_url": "https://get.infranest.io/agent.sh",
  "install_ps1_url": "https://get.infranest.io/agent.ps1",
  "checksums_url": "https://github.com/InfraNest-Infrastructure-Organized/infranest-agent/releases/latest/download/SHA256SUMS",
  "releases_url": "https://github.com/InfraNest-Infrastructure-Organized/infranest-agent/releases",
  "ingest_url": "http://localhost"
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Get a server’s agent snapshot ​

The latest state the monitoring agent reported from inside the server: disk mounts with forecasts, top processes, watched services, containers and ignored units. Also includes the agent’s own health, version status and whether alerts are currently quiet.

GET/organizations/{organization}/cloud-servers/{cloudServer}/agent-snapshot
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-snapshot" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-snapshot" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-snapshot', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-snapshot",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-snapshot', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-snapshot", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "container_names": [],
  "mounts": [
    {
      "mount_point": "/",
      "device": "/dev/sda1",
      "used_bytes": 58411555225,
      "total_bytes": 171798691840,
      "used_percent": 34,
      "inodes_percent": null,
      "collected_at": "2026-01-15T12:00:00.000000Z",
      "usage": null,
      "scan": null,
      "forecast": {
        "days_left": 61,
        "percent_per_day": 1.08,
        "fit": 0.99,
        "from_percent": 34
      }
    }
  ],
  "processes": [],
  "services": [],
  "services_summary": {
    "watched": 0,
    "active": 0,
    "failed": 0,
    "ignored": 0
  },
  "ignored_units": [],
  "containers": null,
  "collected_at": "2026-01-15T12:00:00.000000Z",
  "metrics_source": "agent",
  "uptime_seconds": 3542400,
  "agent_health": null,
  "agent_status": "unknown",
  "agent_latest_version": null,
  "has_token": false,
  "alerts_quiet_until": null
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


List a server’s agent tokens ​

The tokens the monitoring agent on this server can report with, newest first, with who created each and when it was last used. The token values themselves are never returned.

GET/organizations/{organization}/cloud-servers/{cloudServer}/agent-tokens
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-tokens" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-tokens" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-tokens', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-tokens",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-tokens', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-tokens", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
[]
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Override an alert rule for a server ​

Sets this server’s own version of an organization alert, identified by default_id or a catalogue key, with any of operator, threshold, duration_minutes and is_active. Send is_active: false to stop watching it on this server only; anything you leave out is copied from the organization default.

PUT/organizations/{organization}/cloud-servers/{cloudServer}/alert-rule-overrides
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Bodyapplication/json
default_idintegeroptional

This field is required when key is not present.

keystringoptional

This field is required when default_id is not present.

operatorstringoptional

One of: >, <

thresholdnumberoptional
duration_minutesstringoptional

The widest range any kind allows; the kind's own bounds are checked once it is known.

is_activebooleanoptional

Request

sh
curl -X PUT "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rule-overrides" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"key":"cpu_percent","threshold":85}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "key": "cpu_percent",
  "threshold": 85
}
'@
Invoke-RestMethod -Method Put -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rule-overrides" -Headers $headers -ContentType "application/json" -Body $body
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rule-overrides', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'key' => 'cpu_percent',
        'threshold' => 85,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.put(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rule-overrides",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "key": "cpu_percent",
        "threshold": 85,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rule-overrides', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "key": "cpu_percent",
    "threshold": 85
  }),
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	req, err := http.NewRequest("PUT", "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rule-overrides", strings.NewReader(`{"key":"cpu_percent","threshold":85}`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 2,
  "organization_id": 1,
  "server_id": 1,
  "metric": "cpu_percent",
  "operator": ">",
  "threshold": 85,
  "duration_minutes": 15,
  "is_active": true,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "alert_rule_default_id": 1,
  "kind": "metric"
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The default id field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "default_id": [
      "The default id field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
422 validation_failed
429 rate_limited


List a server’s alert rules ​

Every alert in the catalogue for this server, each marked as inherited from the organization, overridden here or not configured, plus any older standalone rules. With active=1 it returns only the rules actually being evaluated, as a flat list.

GET/organizations/{organization}/cloud-servers/{cloudServer}/alert-rules
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "data": [
    {
      "key": "cpu_percent",
      "group": "struggling",
      "kind": "metric",
      "metric": "cpu_percent",
      "agent_only": false,
      "duration_unit": "minutes",
      "duration_bounds": {
        "min": 1,
        "max": 1440
      },
      "recommended": {
        "operator": ">",
        "threshold": 90,
        "duration_minutes": 10
      },
      "origin": "inherited",
      "configured": true,
      "default_active": true,
      "is_active": true,
      "operator": ">",
      "threshold": 85,
      "duration_minutes": 15,
      "default_id": 1,
      "override_id": null,
      "inherited_threshold": null,
      "inherited_duration_minutes": null,
      "is_breaching": false,
      "advisory": false,
      "in_breach_since": null,
      "subject": null
    },
    {
      "key": "memory_percent",
      "group": "struggling",
      "kind": "metric",
      "metric": "memory_percent",
      "agent_only": true,
      "duration_unit": "minutes",
      "duration_bounds": {
        "min": 1,
        "max": 1440
      },
      "recommended": {
        "operator": ">",
        "threshold": 90,
        "duration_minutes": 10
      },
      "origin": "unconfigured",
      "configured": false,
      "default_active": false,
      "is_active": false,
      "operator": ">",
      "threshold": 90,
      "duration_minutes": 10,
      "default_id": null,
      "override_id": null,
      "inherited_threshold": null,
      "inherited_duration_minutes": null,
      "is_breaching": false,
      "advisory": false,
      "in_breach_since": null,
      "subject": null
    }
  ],
  "legacy": [],
  "min_duration_minutes": 1
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Update a server alert rule ​

Changes the operator, threshold, duration_minutes or is_active of one of this server’s rules. Changing the operator or threshold clears any breach the rule was tracking; durations outside the allowed range, or shorter than your plan allows, are refused.

PATCH/organizations/{organization}/cloud-servers/{cloudServer}/alert-rules/{alertRule}
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

alertRuleintegerrequired

The alert rule's ID.

Bodyapplication/json
operatorstringoptional

One of: >, <

thresholdnumberoptional
duration_minutesstringoptional

The widest range any kind allows; the kind's own bounds are checked once it is known.

is_activebooleanoptional

Request

sh
curl -X PATCH "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"threshold":85}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "threshold": 85
}
'@
Invoke-RestMethod -Method Patch -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1" -Headers $headers -ContentType "application/json" -Body $body
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('PATCH', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'threshold' => 85,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.patch(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "threshold": 85,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "threshold": 85
  }),
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	req, err := http.NewRequest("PATCH", "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1", strings.NewReader(`{"threshold":85}`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 1,
  "organization_id": 1,
  "server_id": 1,
  "metric": "cpu_percent",
  "operator": ">",
  "threshold": 85,
  "duration_minutes": 10,
  "is_active": true,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "alert_rule_default_id": null,
  "kind": "metric"
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The operator field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "operator": [
      "The operator field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
422 validation_failed
429 rate_limited


Reset or delete a server alert rule ​

Removes the rule from this server. For an override, the organization’s default applies again; an older standalone rule is simply deleted.

DELETE/organizations/{organization}/cloud-servers/{cloudServer}/alert-rules/{alertRule}
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

alertRuleintegerrequired

The alert rule's ID.

Request

sh
curl -X DELETE "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.delete(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.status_code)
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1', {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("DELETE", "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules/1", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "message": "Deleted."
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
429 rate_limited


Get what needs attention on a server ​

A short summary of the server: its uptime, whether alerts are quiet and until when, and the metric trend closest to crossing its alert threshold. Fields are null when there is nothing to say.

GET/organizations/{organization}/cloud-servers/{cloudServer}/attention
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/attention" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/attention" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/attention', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/attention",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/attention', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/attention", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "uptime_seconds": 3542400,
  "alerts_quiet_until": null,
  "silence": null,
  "trend": {
    "metric": "disk_used_percent",
    "mount_point": "/",
    "current": 34,
    "per_day": 1.08,
    "days_left": 61,
    "threshold": null,
    "also_moving": 0,
    "window_days": 7
  },
  "others_ok": true,
  "certificates": []
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Set a server’s backup price ​

Overrides the monthly backup cost InfraNest counts for this server with backup_price_monthly, net of tax. Send null to go back to the provider’s price; the server’s base price is not affected.

PUT/organizations/{organization}/cloud-servers/{cloudServer}/backup-pricing
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Bodyapplication/json
backup_price_monthlynumber, nullableoptional

Must be at least 0. Must not be greater than 9999999.99.

Request

sh
curl -X PUT "https://api.infranest.io/api/organizations/42/cloud-servers/1/backup-pricing" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"backup_price_monthly":1.58}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "backup_price_monthly": 1.58
}
'@
Invoke-RestMethod -Method Put -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/backup-pricing" -Headers $headers -ContentType "application/json" -Body $body
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/backup-pricing', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'backup_price_monthly' => 1.58,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.put(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/backup-pricing",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "backup_price_monthly": 1.58,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/backup-pricing', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "backup_price_monthly": 1.58
  }),
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	req, err := http.NewRequest("PUT", "https://api.infranest.io/api/organizations/42/cloud-servers/1/backup-pricing", strings.NewReader(`{"backup_price_monthly":1.58}`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 1,
  "organization_id": 1,
  "provider": "hetzner",
  "provider_server_id": "100",
  "name": "web-01",
  "status": "running",
  "server_type": "cpx31",
  "image": "ubuntu-24.04",
  "ipv4": "198.51.100.10",
  "ipv6": "2001:db8:1c1e:5a10::/64",
  "datacenter": "nbg1-dc3",
  "provisioned_at": "2025-12-16T12:00:00.000000Z",
  "deleted_at": null,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "meta": {
    "vcpus": 4,
    "ram_gb": 8,
    "disk_gb": 160,
    "price_monthly": "15.90",
    "price_hourly": "0.0218",
    "location_city": "Nuremberg",
    "location_country": "DE",
    "included_traffic": 21990232555520,
    "outgoing_traffic": 6816972092211,
    "incoming_traffic": 1979120929997,
    "ipv4_dns_ptr": "web-01.northwind.cloud",
    "firewall_enabled": false,
    "backup_window": "22-02"
  },
  "provider_credential_id": 1,
  "price_monthly": null,
  "price_source": "api",
  "price_currency": null,
  "backup_price_override": "1.58",
  "delete_protection": true,
  "untracked_at": null,
  "price_amount": null,
  "billing_interval": "monthly",
  "interval_count": 1,
  "metrics_source": "agent",
  "agent_health": null,
  "monitoring_enabled": true,
  "monitoring_enabled_at": null,
  "volumes_count": 1,
  "hardware": {
    "vcpus": 4,
    "ram_gb": 8,
    "disk_gb": 160,
    "plan": {
      "vcpus": 4,
      "ram_gb": 8,
      "disk_gb": 160
    },
    "machine": {
      "vcpus": null,
      "ram_gb": null,
      "disk_gb": null
    },
    "mismatch": [],
    "disk_unallocated": false
  },
  "live_status": "running",
  "sync_halt": null,
  "volumes": [
    {
      "id": 3,
      "organization_id": 1,
      "cloud_server_id": 1,
      "provider": "hetzner",
      "provider_volume_id": "vol-3",
      "name": "uploads",
      "size_gb": 250,
      "status": "attached",
      "datacenter": "nbg1-dc3",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "provider_credential_id": 1,
      "price_monthly": "12.00",
      "price_source": "api",
      "price_currency": "eur",
      "delete_protection": false,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "native_delete_protection": false,
      "sync_halt": null
    }
  ],
  "tags": [
    {
      "id": 3,
      "name": "Customer-facing",
      "color": "#3b82f6",
      "pivot": {
        "taggable_type": "App\\Models\\CloudServer",
        "taggable_id": 1,
        "tag_id": 3
      }
    },
    {
      "id": 5,
      "name": "Northwind Retail",
      "color": "#0ea5e9",
      "pivot": {
        "taggable_type": "App\\Models\\CloudServer",
        "taggable_id": 1,
        "tag_id": 5
      }
    }
  ],
  "provider_credential": {
    "id": 1,
    "organization_id": 1,
    "provider": "hetzner",
    "label": "Hetzner — Production",
    "enabled": true,
    "verified_at": "2025-10-15T12:00:00.000000Z",
    "last_synced_at": "2026-01-15T11:48:00.000000Z",
    "reconnect_required_at": null,
    "refused_at": null
  },
  "cost": {
    "base": 15.9,
    "currency": "EUR",
    "source": "api",
    "extras": [
      {
        "key": "backups",
        "amount": 1.58,
        "source": "manual",
        "own": true
      },
      {
        "key": "volume",
        "label": "uploads",
        "amount": 12,
        "source": "api",
        "own": false
      }
    ],
    "total": 30.15
  },
  "capabilities": {
    "native_delete_protection": true,
    "server_destroy": true,
    "server_destroy_is_cancellation": false,
    "server_create": true,
    "server_rename": true,
    "console": true,
    "snapshots": true,
    "backups": true,
    "isos": true,
    "rescue": true,
    "placement_groups": true,
    "public_network_toggle": true,
    "scheduled_backups": true,
    "private_networks": true,
    "private_network_attach": true,
    "network_join_on_create": false,
    "network_attach_ip_choice": true,
    "private_network_unfiltered": true,
    "floating_ips": true,
    "networks_creatable": true,
    "network_cidr": true,
    "network_subnets": true,
    "network_routes": true,
    "network_rename": true,
    "network_ip_range_extendable": true,
    "firewalls_creatable": true,
    "firewall_multi_server": true,
    "firewall_renamable": true,
    "firewall_outbound": true,
    "firewall_ipv6": true,
    "firewall_dynamic_ip": true,
    "server_firewall": false,
    "load_balancers_creatable": true,
    "load_balancer_rename": true,
    "load_balancer_algorithm": true,
    "load_balancer_services": true,
    "load_balancer_targets": true,
    "volumes_creatable": true,
    "volume_resize": true,
    "volume_rename": true,
    "volume_native_delete_protection": true,
    "network_native_delete_protection": true,
    "user_data": true,
    "install_flavour": false,
    "images_per_plan": false,
    "metrics": true,
    "metrics_disk_throughput": true,
    "rdns_subnet": true,
    "rdns_address_list": false,
    "reverse_dns": true,
    "snapshot_description": true,
    "snapshot_protection": true
  },
  "capability_blockers": [],
  "rename_refusal": null,
  "agent_silent_after_seconds": 300,
  "agent_refusal": null,
  "uptime_seconds": 3542400
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The backup price monthly field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "backup_price_monthly": [
      "The backup price monthly field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
422 validation_failed
429 rate_limited


List a server’s backups ​

The backups the cloud provider holds for this server, asked live. Empty when the provider account’s access does not cover it; refused when the server has no linked provider account.

GET/organizations/{organization}/cloud-servers/{cloudServer}/backups
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/backups" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/backups" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/backups', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/backups",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/backups', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/backups", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "images": [
    {
      "id": 90000101,
      "type": "backup",
      "status": "available",
      "description": "web-01 backup",
      "created": "2026-01-14T22:06:00+00:00",
      "disk_size": 160,
      "image_size": 17.84,
      "protection": {
        "delete": false
      },
      "bound_to": 100
    },
    {
      "id": 90000102,
      "type": "backup",
      "status": "available",
      "description": "web-01 backup",
      "created": "2026-01-13T22:06:00+00:00",
      "disk_size": 160,
      "image_size": 17.8,
      "protection": {
        "delete": false
      },
      "bound_to": 100
    }
  ]
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Name a container ​

Gives one of the server’s reported containers a display name in InfraNest, identified by container_id. Returns the server’s full list of saved container names; each server has a cap on saved names.

PUT/organizations/{organization}/cloud-servers/{cloudServer}/container-names
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Bodyapplication/json
container_idstringrequired

Must match the regex /\A[0-9a-f]{12,64}\z/.

display_namestringrequired

Must match the regex /\A[^\p{C}]+\z/u. Must not be greater than 100 characters.

Request

sh
curl -X PUT "https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"container_id":"3f2a9c1b7d4e","display_name":"web"}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "container_id": "3f2a9c1b7d4e",
  "display_name": "web"
}
'@
Invoke-RestMethod -Method Put -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names" -Headers $headers -ContentType "application/json" -Body $body
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'container_id' => '3f2a9c1b7d4e',
        'display_name' => 'web',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.put(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "container_id": "3f2a9c1b7d4e",
        "display_name": "web",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "container_id": "3f2a9c1b7d4e",
    "display_name": "web"
  }),
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	req, err := http.NewRequest("PUT", "https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names", strings.NewReader(`{"container_id":"3f2a9c1b7d4e","display_name":"web"}`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "container_names": [
    {
      "container_id": "3f2a9c1b7d4e",
      "display_name": "web"
    }
  ]
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The container id field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "container_id": [
      "The container id field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
422 validation_failed
429 rate_limited


Remove a container name ​

Removes the display name saved for the container given in container_id. Returns the server’s remaining saved container names.

DELETE/organizations/{organization}/cloud-servers/{cloudServer}/container-names
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Bodyapplication/json
container_idstringrequired

Must match the regex /\A[0-9a-f]{12,64}\z/.

Request

sh
curl -X DELETE "https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.delete(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.status_code)
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names', {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("DELETE", "https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "container_names": []
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
429 rate_limited


Get a server’s own firewall ​

The firewall attached to this server, read live from the cloud provider. Refused when the server has no linked provider account.

GET/organizations/{organization}/cloud-servers/{cloudServer}/firewall
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/firewall" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/firewall" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/firewall', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/firewall",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/firewall', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/firewall", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

No success response is recorded for this endpoint yet.


Ignore a failed service ​

Stops a failed system service, named in unit, from raising alerts on this server, without silencing other service failures. Any name is accepted; returns the server’s list of ignored units.

POST/organizations/{organization}/cloud-servers/{cloudServer}/ignored-units
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"unit":"snapd.service"}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "unit": "snapd.service"
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units" -Headers $headers -ContentType "application/json" -Body $body
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'unit' => 'snapd.service',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "unit": "snapd.service",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "unit": "snapd.service"
  }),
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units", strings.NewReader(`{"unit":"snapd.service"}`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "ignored_units": [
    {
      "unit": "snapd.service",
      "ignored_at": "2026-01-15T12:00:00+00:00",
      "ignored_by": "Alex Rivera"
    }
  ]
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "idempotency_in_progress",
  "message": "A request with this Idempotency-Key is still being handled.",
  "hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The name field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "name": [
      "The name field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited


Stop ignoring a failed service ​

Lets the service named in unit raise alerts again on this server; if it is still failed, it counts from now. Returns the remaining ignored units.

DELETE/organizations/{organization}/cloud-servers/{cloudServer}/ignored-units
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl -X DELETE "https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.delete(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.status_code)
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units', {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("DELETE", "https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "ignored_units": []
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
429 rate_limited


List images available to a server ​

The operating system images the cloud provider offers for this server, under images. Empty when the provider account’s access does not cover the catalogue; refused when the server has no linked provider account.

GET/organizations/{organization}/cloud-servers/{cloudServer}/images
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/images" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/images" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/images', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/images",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/images', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/images", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

No success response is recorded for this endpoint yet.


List ISOs available to a server ​

The ISO images the cloud provider offers for this server’s type, under isos. Refused when the server has no linked provider account.

GET/organizations/{organization}/cloud-servers/{cloudServer}/isos
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/isos" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/isos" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/isos', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/isos",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/isos', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/isos", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

No success response is recorded for this endpoint yet.


Get a server’s stored metric series ​

Time series InfraNest has stored for this server, as [unix seconds, value] pairs, oldest first, with the alert threshold that applies to each metric. Pick a comma-separated metrics list, then either a fixed range (live, h1, h12, h24, d7, d30; default h24) or your own window with from and to (ISO 8601) and optionally resolution: raw for every sample (kept for 48 hours, at most 48 hours per request) or hour for hourly averages (at most 92 days per request). Without resolution, raw samples are used when they still cover the window. A longer range is refused with range_too_large. Points are paged with page and per_page (up to 10,000, the default); pagination says how many points the window holds and window the range that was applied.

GET/organizations/{organization}/cloud-servers/{cloudServer}/metric-series
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Query parameters
metricsstringoptional

Comma-separated metrics. Default cpu_percent,memory_percent,worst_mount_percent,load_1.

rangestringoptional

A fixed window: live, h1, h12, h24, d7 or d30. Default h24.

fromstringoptional

Start of your own window, ISO 8601, instead of range.

tostringoptional

End of your own window, ISO 8601; default now.

resolutionstringoptional

raw or hour; default: raw when the samples still cover the window.

per_pageintegeroptional

Points per page, 1 to 10,000. Default 10,000.

pageintegeroptional

Page number, from 1.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/metric-series" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/metric-series" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/metric-series', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/metric-series",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/metric-series', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/metric-series", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "range": "h24",
  "window": {
    "from": "2026-01-14T12:00:00Z",
    "to": "2026-01-15T12:00:00Z"
  },
  "source": "agent",
  "resolution": "raw",
  "series": {
    "cpu_percent": [
      [
        1768392000,
        24.25
      ],
      [
        1768392300,
        23.23
      ]
    ],
    "memory_percent": [
      [
        1768392000,
        62.8
      ],
      [
        1768392300,
        62.43
      ]
    ],
    "worst_mount_percent": [
      [
        1768392000,
        33
      ],
      [
        1768392300,
        33
      ]
    ],
    "load_1": [
      [
        1768392000,
        0.97
      ],
      [
        1768392300,
        0.93
      ]
    ]
  },
  "pagination": {
    "page": 1,
    "per_page": 10000,
    "total": 289,
    "last_page": 1
  },
  "thresholds": {
    "cpu_percent": {
      "operator": ">",
      "threshold": 85,
      "duration_minutes": 15
    },
    "memory_percent": null,
    "worst_mount_percent": null,
    "load_1": null
  },
  "facts": {
    "vcpus": 4,
    "worst_mount": {
      "mount_point": "/",
      "used_bytes": 58411555225,
      "total_bytes": 171798691840,
      "days_left": 61
    }
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Get a server’s provider metrics ​

CPU, disk and network figures asked live from the cloud provider. Pick the figures with types (default cpu,disk,network) and set the window with start, end and step in seconds (default: the last hour at 60 seconds); refused when the server has no linked provider account.

GET/organizations/{organization}/cloud-servers/{cloudServer}/metrics
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/metrics" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/metrics" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/metrics', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/metrics",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/metrics', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/metrics", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "metrics": {
    "start": "2026-01-15T11:00:00+00:00",
    "end": "2026-01-15T12:00:00+00:00",
    "step": 60,
    "time_series": {
      "cpu": {
        "values": [
          [
            1768474800,
            "22.12"
          ],
          [
            1768475100,
            "23.11"
          ]
        ]
      },
      "network.0.bandwidth.in": {
        "values": [
          [
            1768474800,
            "16381032"
          ],
          [
            1768475100,
            "18508096"
          ]
        ]
      },
      "network.0.bandwidth.out": {
        "values": [
          [
            1768474800,
            "38222409"
          ],
          [
            1768475100,
            "43185557"
          ]
        ]
      },
      "disk.0.bandwidth.read": {
        "values": [
          [
            1768474800,
            "5460344"
          ],
          [
            1768475100,
            "6169365"
          ]
        ]
      },
      "disk.0.bandwidth.write": {
        "values": [
          [
            1768474800,
            "8190516"
          ],
          [
            1768475100,
            "9254048"
          ]
        ]
      }
    }
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Turn on monitoring for a server ​

Starts monitoring the server in InfraNest and returns how many monitored servers your plan allows and uses. Refused when you have reached that limit; repeating it on a monitored server changes nothing.

POST/organizations/{organization}/cloud-servers/{cloudServer}/monitoring
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "monitoring_enabled": true,
  "monitoring_enabled_at": null,
  "usage": 11,
  "limit": null
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "idempotency_in_progress",
  "message": "A request with this Idempotency-Key is still being handled.",
  "hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The name field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "name": [
      "The name field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited


Turn off monitoring for a server ​

Stops monitoring the server and frees its place in your plan’s monitored-server count. The server itself is not affected.

DELETE/organizations/{organization}/cloud-servers/{cloudServer}/monitoring
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl -X DELETE "https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.delete(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.status_code)
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring', {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("DELETE", "https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "monitoring_enabled": false,
  "monitoring_enabled_at": null,
  "usage": 10,
  "limit": null
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
429 rate_limited


Set a server’s price ​

Sets a manual price for the server in InfraNest, with optional currency and billing interval. A manual price is no longer overwritten by the provider’s price at each sync; nothing changes at the provider.

PUT/organizations/{organization}/cloud-servers/{cloudServer}/pricing
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl -X PUT "https://api.infranest.io/api/organizations/42/cloud-servers/1/pricing" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"price_monthly":7.9,"currency":"EUR"}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "price_monthly": 7.9,
  "currency": "EUR"
}
'@
Invoke-RestMethod -Method Put -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/pricing" -Headers $headers -ContentType "application/json" -Body $body
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/pricing', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'price_monthly' => 7.9,
        'currency' => 'EUR',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.put(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/pricing",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "price_monthly": 7.9,
        "currency": "EUR",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/pricing', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "price_monthly": 7.9,
    "currency": "EUR"
  }),
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	req, err := http.NewRequest("PUT", "https://api.infranest.io/api/organizations/42/cloud-servers/1/pricing", strings.NewReader(`{"price_monthly":7.9,"currency":"EUR"}`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 1,
  "organization_id": 1,
  "provider": "hetzner",
  "provider_server_id": "100",
  "name": "web-01",
  "status": "running",
  "server_type": "cpx31",
  "image": "ubuntu-24.04",
  "ipv4": "198.51.100.10",
  "ipv6": "2001:db8:1c1e:5a10::/64",
  "datacenter": "nbg1-dc3",
  "provisioned_at": "2025-12-16T12:00:00.000000Z",
  "deleted_at": null,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "meta": {
    "vcpus": 4,
    "ram_gb": 8,
    "disk_gb": 160,
    "price_monthly": "15.90",
    "price_hourly": "0.0218",
    "location_city": "Nuremberg",
    "location_country": "DE",
    "included_traffic": 21990232555520,
    "outgoing_traffic": 6816972092211,
    "incoming_traffic": 1979120929997,
    "ipv4_dns_ptr": "web-01.northwind.cloud",
    "firewall_enabled": false,
    "backup_window": "22-02"
  },
  "provider_credential_id": 1,
  "price_monthly": "7.90",
  "price_source": "manual",
  "price_currency": null,
  "backup_price_override": null,
  "delete_protection": true,
  "untracked_at": null,
  "price_amount": "7.9000",
  "billing_interval": "monthly",
  "interval_count": 1,
  "metrics_source": "agent",
  "agent_health": null,
  "monitoring_enabled": true,
  "monitoring_enabled_at": null,
  "volumes_count": 1,
  "hardware": {
    "vcpus": 4,
    "ram_gb": 8,
    "disk_gb": 160,
    "plan": {
      "vcpus": 4,
      "ram_gb": 8,
      "disk_gb": 160
    },
    "machine": {
      "vcpus": null,
      "ram_gb": null,
      "disk_gb": null
    },
    "mismatch": [],
    "disk_unallocated": false
  },
  "live_status": "running",
  "sync_halt": null,
  "volumes": [
    {
      "id": 3,
      "organization_id": 1,
      "cloud_server_id": 1,
      "provider": "hetzner",
      "provider_volume_id": "vol-3",
      "name": "uploads",
      "size_gb": 250,
      "status": "attached",
      "datacenter": "nbg1-dc3",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "provider_credential_id": 1,
      "price_monthly": "12.00",
      "price_source": "api",
      "price_currency": "eur",
      "delete_protection": false,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "native_delete_protection": false,
      "sync_halt": null
    }
  ],
  "tags": [
    {
      "id": 3,
      "name": "Customer-facing",
      "color": "#3b82f6",
      "pivot": {
        "taggable_type": "App\\Models\\CloudServer",
        "taggable_id": 1,
        "tag_id": 3
      }
    },
    {
      "id": 5,
      "name": "Northwind Retail",
      "color": "#0ea5e9",
      "pivot": {
        "taggable_type": "App\\Models\\CloudServer",
        "taggable_id": 1,
        "tag_id": 5
      }
    }
  ],
  "provider_credential": {
    "id": 1,
    "organization_id": 1,
    "provider": "hetzner",
    "label": "Hetzner — Production",
    "enabled": true,
    "verified_at": "2025-10-15T12:00:00.000000Z",
    "last_synced_at": "2026-01-15T11:48:00.000000Z",
    "reconnect_required_at": null,
    "refused_at": null
  },
  "cost": {
    "base": 7.9,
    "currency": "EUR",
    "source": "manual",
    "extras": [
      {
        "key": "backups",
        "amount": 1.58,
        "source": "computed",
        "own": true
      },
      {
        "key": "volume",
        "label": "uploads",
        "amount": 12,
        "source": "api",
        "own": false
      }
    ],
    "total": 22.15
  },
  "capabilities": {
    "native_delete_protection": true,
    "server_destroy": true,
    "server_destroy_is_cancellation": false,
    "server_create": true,
    "server_rename": true,
    "console": true,
    "snapshots": true,
    "backups": true,
    "isos": true,
    "rescue": true,
    "placement_groups": true,
    "public_network_toggle": true,
    "scheduled_backups": true,
    "private_networks": true,
    "private_network_attach": true,
    "network_join_on_create": false,
    "network_attach_ip_choice": true,
    "private_network_unfiltered": true,
    "floating_ips": true,
    "networks_creatable": true,
    "network_cidr": true,
    "network_subnets": true,
    "network_routes": true,
    "network_rename": true,
    "network_ip_range_extendable": true,
    "firewalls_creatable": true,
    "firewall_multi_server": true,
    "firewall_renamable": true,
    "firewall_outbound": true,
    "firewall_ipv6": true,
    "firewall_dynamic_ip": true,
    "server_firewall": false,
    "load_balancers_creatable": true,
    "load_balancer_rename": true,
    "load_balancer_algorithm": true,
    "load_balancer_services": true,
    "load_balancer_targets": true,
    "volumes_creatable": true,
    "volume_resize": true,
    "volume_rename": true,
    "volume_native_delete_protection": true,
    "network_native_delete_protection": true,
    "user_data": true,
    "install_flavour": false,
    "images_per_plan": false,
    "metrics": true,
    "metrics_disk_throughput": true,
    "rdns_subnet": true,
    "rdns_address_list": false,
    "reverse_dns": true,
    "snapshot_description": true,
    "snapshot_protection": true
  },
  "capability_blockers": [],
  "rename_refusal": null,
  "agent_silent_after_seconds": 300,
  "agent_refusal": null,
  "uptime_seconds": 3542400
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The name field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "name": [
      "The name field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
422 validation_failed
429 rate_limited


List a server’s provider actions ​

The recent actions the cloud provider reports for this server, asked live. Empty when the provider account’s access does not cover it; refused when the server has no linked provider account.

GET/organizations/{organization}/cloud-servers/{cloudServer}/provider-actions
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/provider-actions" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/provider-actions" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/provider-actions', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/provider-actions",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/provider-actions', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/1/provider-actions", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

No success response is recorded for this endpoint yet.


Reset a server’s price ​

Drops the manual price and goes back to the price last synced from the provider. Returns the server with its updated cost breakdown.

POST/organizations/{organization}/cloud-servers/{cloudServer}/reset-pricing
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/cloud-servers/1/reset-pricing" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/reset-pricing" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/reset-pricing', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/reset-pricing",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/reset-pricing', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/cloud-servers/1/reset-pricing", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 1,
  "organization_id": 1,
  "provider": "hetzner",
  "provider_server_id": "100",
  "name": "web-01",
  "status": "running",
  "server_type": "cpx31",
  "image": "ubuntu-24.04",
  "ipv4": "198.51.100.10",
  "ipv6": "2001:db8:1c1e:5a10::/64",
  "datacenter": "nbg1-dc3",
  "provisioned_at": "2025-12-16T12:00:00.000000Z",
  "deleted_at": null,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "meta": {
    "vcpus": 4,
    "ram_gb": 8,
    "disk_gb": 160,
    "price_monthly": "15.90",
    "price_hourly": "0.0218",
    "location_city": "Nuremberg",
    "location_country": "DE",
    "included_traffic": 21990232555520,
    "outgoing_traffic": 6816972092211,
    "incoming_traffic": 1979120929997,
    "ipv4_dns_ptr": "web-01.northwind.cloud",
    "firewall_enabled": false,
    "backup_window": "22-02"
  },
  "provider_credential_id": 1,
  "price_monthly": "15.90",
  "price_source": "api",
  "price_currency": "EUR",
  "backup_price_override": null,
  "delete_protection": true,
  "untracked_at": null,
  "price_amount": "15.9000",
  "billing_interval": "monthly",
  "interval_count": 1,
  "metrics_source": "agent",
  "agent_health": null,
  "monitoring_enabled": true,
  "monitoring_enabled_at": null,
  "volumes_count": 1,
  "hardware": {
    "vcpus": 4,
    "ram_gb": 8,
    "disk_gb": 160,
    "plan": {
      "vcpus": 4,
      "ram_gb": 8,
      "disk_gb": 160
    },
    "machine": {
      "vcpus": null,
      "ram_gb": null,
      "disk_gb": null
    },
    "mismatch": [],
    "disk_unallocated": false
  },
  "live_status": "running",
  "sync_halt": null,
  "volumes": [
    {
      "id": 3,
      "organization_id": 1,
      "cloud_server_id": 1,
      "provider": "hetzner",
      "provider_volume_id": "vol-3",
      "name": "uploads",
      "size_gb": 250,
      "status": "attached",
      "datacenter": "nbg1-dc3",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "provider_credential_id": 1,
      "price_monthly": "12.00",
      "price_source": "api",
      "price_currency": "eur",
      "delete_protection": false,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "native_delete_protection": false,
      "sync_halt": null
    }
  ],
  "tags": [
    {
      "id": 3,
      "name": "Customer-facing",
      "color": "#3b82f6",
      "pivot": {
        "taggable_type": "App\\Models\\CloudServer",
        "taggable_id": 1,
        "tag_id": 3
      }
    },
    {
      "id": 5,
      "name": "Northwind Retail",
      "color": "#0ea5e9",
      "pivot": {
        "taggable_type": "App\\Models\\CloudServer",
        "taggable_id": 1,
        "tag_id": 5
      }
    }
  ],
  "provider_credential": {
    "id": 1,
    "organization_id": 1,
    "provider": "hetzner",
    "label": "Hetzner — Production",
    "enabled": true,
    "verified_at": "2025-10-15T12:00:00.000000Z",
    "last_synced_at": "2026-01-15T11:48:00.000000Z",
    "reconnect_required_at": null,
    "refused_at": null
  },
  "cost": {
    "base": 15.9,
    "currency": "EUR",
    "source": "api",
    "extras": [
      {
        "key": "backups",
        "amount": 3.18,
        "source": "computed",
        "own": true
      },
      {
        "key": "volume",
        "label": "uploads",
        "amount": 12,
        "source": "api",
        "own": false
      }
    ],
    "total": 31.75
  },
  "capabilities": {
    "native_delete_protection": true,
    "server_destroy": true,
    "server_destroy_is_cancellation": false,
    "server_create": true,
    "server_rename": true,
    "console": true,
    "snapshots": true,
    "backups": true,
    "isos": true,
    "rescue": true,
    "placement_groups": true,
    "public_network_toggle": true,
    "scheduled_backups": true,
    "private_networks": true,
    "private_network_attach": true,
    "network_join_on_create": false,
    "network_attach_ip_choice": true,
    "private_network_unfiltered": true,
    "floating_ips": true,
    "networks_creatable": true,
    "network_cidr": true,
    "network_subnets": true,
    "network_routes": true,
    "network_rename": true,
    "network_ip_range_extendable": true,
    "firewalls_creatable": true,
    "firewall_multi_server": true,
    "firewall_renamable": true,
    "firewall_outbound": true,
    "firewall_ipv6": true,
    "firewall_dynamic_ip": true,
    "server_firewall": false,
    "load_balancers_creatable": true,
    "load_balancer_rename": true,
    "load_balancer_algorithm": true,
    "load_balancer_services": true,
    "load_balancer_targets": true,
    "volumes_creatable": true,
    "volume_resize": true,
    "volume_rename": true,
    "volume_native_delete_protection": true,
    "network_native_delete_protection": true,
    "user_data": true,
    "install_flavour": false,
    "images_per_plan": false,
    "metrics": true,
    "metrics_disk_throughput": true,
    "rdns_subnet": true,
    "rdns_address_list": false,
    "reverse_dns": true,
    "snapshot_description": true,
    "snapshot_protection": true
  },
  "capability_blockers": [],
  "rename_refusal": null,
  "agent_silent_after_seconds": 300,
  "agent_refusal": null,
  "uptime_seconds": 3542400
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "idempotency_in_progress",
  "message": "A request with this Idempotency-Key is still being handled.",
  "hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The name field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "name": [
      "The name field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited


Snooze a server’s alerts ​

Silences the server’s alerts for minutes (5 to 1440) by creating a short maintenance window, and returns when it ends. Refused when your plan does not include maintenance windows.

POST/organizations/{organization}/cloud-servers/{cloudServer}/snooze
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Bodyapplication/json
minutesintegeroptional

Capped at a day. Beyond that somebody wants a scheduled window with a name and a reason, which is the full form — a snooze that can run for a week is a way to switch monitoring off and forget you did. Must be at least 5. Must not be greater than 1440.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"minutes":60}'
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
$body = @'
{
  "minutes": 60
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze" -Headers $headers -ContentType "application/json" -Body $body
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'minutes' => 60,
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "minutes": 60,
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "minutes": 60
  }),
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze", strings.NewReader(`{"minutes":60}`))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "maintenance_window_id": 5,
  "until": "2026-01-15T13:00:00+00:00"
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "idempotency_in_progress",
  "message": "A request with this Idempotency-Key is still being handled.",
  "hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The minutes field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "minutes": [
      "The minutes field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited


End a server’s snooze ​

Ends a snooze before it runs out. Scheduled maintenance windows are left alone, so the response says whether anything was ended and until when alerts are still quiet.

DELETE/organizations/{organization}/cloud-servers/{cloudServer}/snooze
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl -X DELETE "https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.delete(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.status_code)
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze', {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("DELETE", "https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "ended": 0,
  "alerts_quiet_until": null
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
429 rate_limited


Stop tracking a server ​

Hides the server from every list, cost and alert in InfraNest without touching it at the provider, where it keeps running. It no longer counts towards your plan, and tracking it again restores its history.

POST/organizations/{organization}/cloud-servers/{cloudServer}/untrack
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudServerintegerrequired

The cloud server's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/cloud-servers/1/untrack" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/untrack" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/untrack', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/untrack",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/untrack', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/cloud-servers/1/untrack", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "message": "Server is no longer tracked."
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "idempotency_in_progress",
  "message": "A request with this Idempotency-Key is still being handled.",
  "hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The name field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "name": [
      "The name field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited


Track a server again ​

Brings an untracked server back into lists, costs and alerts, with its history, tags and alert rules intact. It counts towards your plan again, so it is refused when you have reached your server limit.

POST/organizations/{organization}/cloud-servers/{serverId}/retrack
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

serverIdintegerrequired

The server id's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/cloud-servers/1/retrack" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/1/retrack" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/cloud-servers/1/retrack', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/cloud-servers/1/retrack",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/1/retrack', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/cloud-servers/1/retrack", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 1,
  "organization_id": 1,
  "provider": "hetzner",
  "provider_server_id": "100",
  "name": "web-01",
  "status": "running",
  "server_type": "cpx31",
  "image": "ubuntu-24.04",
  "ipv4": "198.51.100.10",
  "ipv6": "2001:db8:1c1e:5a10::/64",
  "datacenter": "nbg1-dc3",
  "provisioned_at": "2025-12-16T12:00:00.000000Z",
  "deleted_at": null,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "meta": {
    "vcpus": 4,
    "ram_gb": 8,
    "disk_gb": 160,
    "price_monthly": "15.90",
    "price_hourly": "0.0218",
    "location_city": "Nuremberg",
    "location_country": "DE",
    "included_traffic": 21990232555520,
    "outgoing_traffic": 6816972092211,
    "incoming_traffic": 1979120929997,
    "ipv4_dns_ptr": "web-01.northwind.cloud",
    "firewall_enabled": false,
    "backup_window": "22-02"
  },
  "provider_credential_id": 1,
  "price_monthly": null,
  "price_source": "api",
  "price_currency": null,
  "backup_price_override": null,
  "delete_protection": true,
  "untracked_at": null,
  "price_amount": null,
  "billing_interval": "monthly",
  "interval_count": 1,
  "metrics_source": "agent",
  "agent_health": null,
  "monitoring_enabled": true,
  "monitoring_enabled_at": null,
  "volumes_count": 1,
  "hardware": {
    "vcpus": 4,
    "ram_gb": 8,
    "disk_gb": 160,
    "plan": {
      "vcpus": 4,
      "ram_gb": 8,
      "disk_gb": 160
    },
    "machine": {
      "vcpus": null,
      "ram_gb": null,
      "disk_gb": null
    },
    "mismatch": [],
    "disk_unallocated": false
  },
  "live_status": "running",
  "sync_halt": null,
  "volumes": [
    {
      "id": 3,
      "organization_id": 1,
      "cloud_server_id": 1,
      "provider": "hetzner",
      "provider_volume_id": "vol-3",
      "name": "uploads",
      "size_gb": 250,
      "status": "attached",
      "datacenter": "nbg1-dc3",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "provider_credential_id": 1,
      "price_monthly": "12.00",
      "price_source": "api",
      "price_currency": "eur",
      "delete_protection": false,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "native_delete_protection": false,
      "sync_halt": null
    }
  ],
  "tags": [
    {
      "id": 3,
      "name": "Customer-facing",
      "color": "#3b82f6",
      "pivot": {
        "taggable_type": "App\\Models\\CloudServer",
        "taggable_id": 1,
        "tag_id": 3
      }
    },
    {
      "id": 5,
      "name": "Northwind Retail",
      "color": "#0ea5e9",
      "pivot": {
        "taggable_type": "App\\Models\\CloudServer",
        "taggable_id": 1,
        "tag_id": 5
      }
    }
  ],
  "provider_credential": {
    "id": 1,
    "organization_id": 1,
    "provider": "hetzner",
    "label": "Hetzner — Production",
    "enabled": true,
    "verified_at": "2025-10-15T12:00:00.000000Z",
    "last_synced_at": "2026-01-15T11:48:00.000000Z",
    "reconnect_required_at": null,
    "refused_at": null
  },
  "cost": {
    "base": 15.9,
    "currency": "EUR",
    "source": "api",
    "extras": [
      {
        "key": "backups",
        "amount": 3.18,
        "source": "computed",
        "own": true
      },
      {
        "key": "volume",
        "label": "uploads",
        "amount": 12,
        "source": "api",
        "own": false
      }
    ],
    "total": 31.75
  },
  "capabilities": {
    "native_delete_protection": true,
    "server_destroy": true,
    "server_destroy_is_cancellation": false,
    "server_create": true,
    "server_rename": true,
    "console": true,
    "snapshots": true,
    "backups": true,
    "isos": true,
    "rescue": true,
    "placement_groups": true,
    "public_network_toggle": true,
    "scheduled_backups": true,
    "private_networks": true,
    "private_network_attach": true,
    "network_join_on_create": false,
    "network_attach_ip_choice": true,
    "private_network_unfiltered": true,
    "floating_ips": true,
    "networks_creatable": true,
    "network_cidr": true,
    "network_subnets": true,
    "network_routes": true,
    "network_rename": true,
    "network_ip_range_extendable": true,
    "firewalls_creatable": true,
    "firewall_multi_server": true,
    "firewall_renamable": true,
    "firewall_outbound": true,
    "firewall_ipv6": true,
    "firewall_dynamic_ip": true,
    "server_firewall": false,
    "load_balancers_creatable": true,
    "load_balancer_rename": true,
    "load_balancer_algorithm": true,
    "load_balancer_services": true,
    "load_balancer_targets": true,
    "volumes_creatable": true,
    "volume_resize": true,
    "volume_rename": true,
    "volume_native_delete_protection": true,
    "network_native_delete_protection": true,
    "user_data": true,
    "install_flavour": false,
    "images_per_plan": false,
    "metrics": true,
    "metrics_disk_throughput": true,
    "rdns_subnet": true,
    "rdns_address_list": false,
    "reverse_dns": true,
    "snapshot_description": true,
    "snapshot_protection": true
  },
  "capability_blockers": [],
  "rename_refusal": null,
  "agent_silent_after_seconds": 300,
  "agent_refusal": null,
  "uptime_seconds": 3542400
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "idempotency_in_progress",
  "message": "A request with this Idempotency-Key is still being handled.",
  "hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The name field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "name": [
      "The name field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited


List servers with their latest metrics ​

Every server in the organization with its latest CPU, memory, disk, load and network readings, its alert-rule counts and whether it is breaching, a page at a time. Monitored servers come first; filter with search, credential, tag or status (for example breaching, norules, notreporting, monitored).

GET/organizations/{organization}/cloud-servers/metrics-overview
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-servers/metrics-overview" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-servers/metrics-overview" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-servers/metrics-overview', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-servers/metrics-overview",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-servers/metrics-overview', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-servers/metrics-overview", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "current_page": 1,
  "data": [
    {
      "id": 12,
      "organization_id": 1,
      "provider": "digitalocean",
      "provider_server_id": "111",
      "name": "queue-01",
      "status": "running",
      "server_type": "s-4vcpu-8gb",
      "image": "ubuntu-24-04-x64",
      "ipv4": "192.0.2.40",
      "ipv6": "2001:db8:3:d0::a22:1/64",
      "datacenter": "fra1",
      "provisioned_at": "2025-08-06T12:00:00.000000Z",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "meta": {
        "vcpus": 4,
        "ram_gb": 8,
        "disk_gb": 160,
        "price_monthly": "48.00",
        "price_hourly": "0.0658",
        "location_city": "Frankfurt",
        "location_country": "DE",
        "included_traffic": 5497558138880,
        "outgoing_traffic": 1044536046387,
        "incoming_traffic": 384829069722,
        "ipv4_dns_ptr": "queue-01.northwind.cloud",
        "firewall_enabled": false
      },
      "provider_credential_id": 9,
      "price_monthly": null,
      "price_source": "api",
      "price_currency": null,
      "backup_price_override": null,
      "delete_protection": false,
      "untracked_at": null,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "metrics_source": "agent",
      "monitoring_enabled": true,
      "monitoring_enabled_at": null,
      "breached_rules": 0,
      "cpu_percent": 64.03,
      "network_in_bps": 14121908,
      "network_out_bps": 10591431,
      "memory_percent": 67.71,
      "worst_mount_percent": 55,
      "load_1": 2.56,
      "load_5": 2.49,
      "load_15": 2.42,
      "collected_at": "2026-01-13 12:05:00",
      "agent_last_seen_at": null,
      "agent_tokens_count": 0,
      "silence": null,
      "active_rules": 1,
      "in_breach": false,
      "coverage": "agent",
      "provider_metrics": true,
      "worst_mount_point": "/",
      "disk_forecast": {
        "mount_point": "/",
        "days_left": 39,
        "percent_per_day": 1.08,
        "fit": 0.99,
        "from_percent": 57
      },
      "load_24h": [
        2.28,
        2.11
      ],
      "agent_version": null,
      "agent_status": "unknown",
      "agent_refusal": null,
      "hardware": {
        "vcpus": 4,
        "ram_gb": 8,
        "disk_gb": 160,
        "plan": {
          "vcpus": 4,
          "ram_gb": 8,
          "disk_gb": 160
        },
        "machine": {
          "vcpus": null,
          "ram_gb": null,
          "disk_gb": null
        },
        "mismatch": [],
        "disk_unallocated": false
      },
      "live_status": "running",
      "sync_halt": null,
      "tags": [
        {
          "id": 1,
          "name": "Production",
          "color": "#ef4444",
          "pivot": {
            "taggable_type": "App\\Models\\CloudServer",
            "taggable_id": 12,
            "tag_id": 1
          }
        }
      ]
    },
    {
      "id": 10,
      "organization_id": 1,
      "provider": "digitalocean",
      "provider_server_id": "109",
      "name": "staging-web-01",
      "status": "running",
      "server_type": "s-2vcpu-4gb",
      "image": "ubuntu-24-04-x64",
      "ipv4": "192.0.2.10",
      "ipv6": "2001:db8:800:c1::a10:1/64",
      "datacenter": "ams3",
      "provisioned_at": "2025-08-30T12:00:00.000000Z",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "meta": {
        "vcpus": 2,
        "ram_gb": 4,
        "disk_gb": 80,
        "price_monthly": "24.00",
        "price_hourly": "0.0329",
        "location_city": "Amsterdam",
        "location_country": "NL",
        "included_traffic": 4398046511104,
        "outgoing_traffic": 483785116221,
        "incoming_traffic": 219902325555,
        "ipv4_dns_ptr": "staging-web-01.northwind.cloud",
        "firewall_enabled": false
      },
      "provider_credential_id": 9,
      "price_monthly": null,
      "price_source": "api",
      "price_currency": null,
      "backup_price_override": null,
      "delete_protection": false,
      "untracked_at": null,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "metrics_source": "provider",
      "monitoring_enabled": true,
      "monitoring_enabled_at": null,
      "breached_rules": 0,
      "cpu_percent": 8.67,
      "network_in_bps": 3530477,
      "network_out_bps": 7060954,
      "memory_percent": null,
      "worst_mount_percent": null,
      "load_1": null,
      "load_5": null,
      "load_15": null,
      "collected_at": "2026-01-13 12:05:00",
      "agent_last_seen_at": null,
      "agent_tokens_count": 0,
      "silence": null,
      "active_rules": 1,
      "in_breach": false,
      "coverage": "provider",
      "provider_metrics": true,
      "worst_mount_point": null,
      "disk_forecast": null,
      "load_24h": null,
      "agent_version": null,
      "agent_status": "unknown",
      "agent_refusal": null,
      "hardware": {
        "vcpus": 2,
        "ram_gb": 4,
        "disk_gb": 80,
        "plan": {
          "vcpus": 2,
          "ram_gb": 4,
          "disk_gb": 80
        },
        "machine": {
          "vcpus": null,
          "ram_gb": null,
          "disk_gb": null
        },
        "mismatch": [],
        "disk_unallocated": false
      },
      "live_status": "running",
      "sync_halt": null,
      "tags": [
        {
          "id": 2,
          "name": "Staging",
          "color": "#f59e0b",
          "pivot": {
            "taggable_type": "App\\Models\\CloudServer",
            "taggable_id": 10,
            "tag_id": 2
          }
        }
      ]
    }
  ],
  "first_page_url": "http://localhost/api/organizations/1/cloud-servers/metrics-overview?page=1",
  "from": 1,
  "last_page": 1,
  "last_page_url": "http://localhost/api/organizations/1/cloud-servers/metrics-overview?page=1",
  "links": [
    {
      "url": null,
      "label": "&laquo; Previous",
      "page": null,
      "active": false
    },
    {
      "url": "http://localhost/api/organizations/1/cloud-servers/metrics-overview?page=1",
      "label": "1",
      "page": 1,
      "active": true
    }
  ],
  "next_page_url": null,
  "path": "http://localhost/api/organizations/1/cloud-servers/metrics-overview",
  "per_page": 25,
  "prev_page_url": null,
  "to": 14,
  "total": 14,
  "meta": {
    "counts": {
      "total": 14,
      "breaching": 0,
      "noagent": 9,
      "notreporting": 4,
      "ok": 10,
      "norules": 0,
      "notmonitored": 3,
      "monitored": 11,
      "avgCpu": 29
    },
    "agent_silent_after_seconds": 300,
    "counted_at": "2026-01-15T12:00:00.000000Z",
    "integrations": [
      {
        "id": 9,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging"
      },
      {
        "id": 1,
        "provider": "hetzner",
        "label": "Hetzner — Production"
      }
    ],
    "tags": [
      {
        "id": 3,
        "name": "Customer-facing",
        "color": "#3b82f6"
      },
      {
        "id": 6,
        "name": "Northwind Platform",
        "color": "#14b8a6"
      }
    ]
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

Cloud snapshots ​

List snapshots ​

Every server snapshot InfraNest tracks in the organization, a page at a time, with the server it belongs to. Filter with server_id, status, credential or search, and sort with sort and dir.

GET/organizations/{organization}/cloud-snapshots
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-snapshots" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-snapshots" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-snapshots', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-snapshots",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-snapshots', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-snapshots", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "current_page": 1,
  "data": [
    {
      "id": 3,
      "organization_id": 1,
      "provider_credential_id": null,
      "cloud_server_id": 1,
      "provider": "hetzner",
      "provider_snapshot_id": "snap-302",
      "name": "web-01 golden image",
      "description": "Base image the web tier is rebuilt from.",
      "status": "available",
      "disk_size_gb": 80,
      "image_size_gb": 6.2,
      "source_server_name": "web-01",
      "protection_delete": true,
      "created_at": "2025-12-12T12:00:00.000000Z",
      "updated_at": "2025-12-12T12:00:00.000000Z",
      "deleted_at": null,
      "price_monthly": "0.07",
      "price_amount": null,
      "price_currency": "EUR",
      "price_source": "api",
      "billing_interval": "monthly",
      "interval_count": 1,
      "capabilities": [],
      "provider_credential": null,
      "server": {
        "id": 1,
        "name": "web-01",
        "ipv4": "198.51.100.10",
        "status": "running",
        "hardware": {
          "vcpus": null,
          "ram_gb": null,
          "disk_gb": null,
          "plan": {
            "vcpus": null,
            "ram_gb": null,
            "disk_gb": null
          },
          "machine": {
            "vcpus": null,
            "ram_gb": null,
            "disk_gb": null
          },
          "mismatch": [],
          "disk_unallocated": false
        },
        "live_status": null,
        "sync_halt": null
      }
    },
    {
      "id": 2,
      "organization_id": 1,
      "provider_credential_id": null,
      "cloud_server_id": 4,
      "provider": "hetzner",
      "provider_snapshot_id": "snap-301",
      "name": "db-01 nightly",
      "description": null,
      "status": "available",
      "disk_size_gb": 40,
      "image_size_gb": 11.1,
      "source_server_name": "db-01",
      "protection_delete": false,
      "created_at": "2026-01-14T12:00:00.000000Z",
      "updated_at": "2026-01-14T12:00:00.000000Z",
      "deleted_at": null,
      "price_monthly": "0.13",
      "price_amount": null,
      "price_currency": "EUR",
      "price_source": "api",
      "billing_interval": "monthly",
      "interval_count": 1,
      "capabilities": [],
      "provider_credential": null,
      "server": {
        "id": 4,
        "name": "db-01",
        "ipv4": "198.51.100.30",
        "status": "running",
        "hardware": {
          "vcpus": null,
          "ram_gb": null,
          "disk_gb": null,
          "plan": {
            "vcpus": null,
            "ram_gb": null,
            "disk_gb": null
          },
          "machine": {
            "vcpus": null,
            "ram_gb": null,
            "disk_gb": null
          },
          "mismatch": [],
          "disk_unallocated": false
        },
        "live_status": null,
        "sync_halt": null
      }
    }
  ],
  "first_page_url": "http://localhost/api/organizations/1/cloud-snapshots?page=1",
  "from": 1,
  "last_page": 1,
  "last_page_url": "http://localhost/api/organizations/1/cloud-snapshots?page=1",
  "links": [
    {
      "url": null,
      "label": "&laquo; Previous",
      "page": null,
      "active": false
    },
    {
      "url": "http://localhost/api/organizations/1/cloud-snapshots?page=1",
      "label": "1",
      "page": 1,
      "active": true
    }
  ],
  "next_page_url": null,
  "path": "http://localhost/api/organizations/1/cloud-snapshots",
  "per_page": 25,
  "prev_page_url": null,
  "to": 6,
  "total": 6,
  "meta": {
    "counts": {
      "total": 6,
      "available": 6,
      "creating": 0,
      "unavailable": 0
    },
    "integrations": []
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Get a snapshot ​

One snapshot with the server it was taken from.

GET/organizations/{organization}/cloud-snapshots/{cloudSnapshot}
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudSnapshotintegerrequired

The cloud snapshot's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-snapshots/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-snapshots/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-snapshots/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-snapshots/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-snapshots/1', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-snapshots/1", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 1,
  "organization_id": 1,
  "provider_credential_id": null,
  "cloud_server_id": 4,
  "provider": "hetzner",
  "provider_snapshot_id": "snap-300",
  "name": "db-01 before schema migration",
  "description": "Taken automatically before the 2026-08 migration.",
  "status": "available",
  "disk_size_gb": 40,
  "image_size_gb": 11.4,
  "source_server_name": "db-01",
  "protection_delete": true,
  "created_at": "2026-01-06T12:00:00.000000Z",
  "updated_at": "2026-01-06T12:00:00.000000Z",
  "deleted_at": null,
  "price_monthly": "0.14",
  "price_amount": null,
  "price_currency": "EUR",
  "price_source": "api",
  "billing_interval": "monthly",
  "interval_count": 1,
  "provider_credential": null,
  "server": {
    "id": 4,
    "name": "db-01",
    "ipv4": "198.51.100.30",
    "status": "running",
    "hardware": {
      "vcpus": null,
      "ram_gb": null,
      "disk_gb": null,
      "plan": {
        "vcpus": null,
        "ram_gb": null,
        "disk_gb": null
      },
      "machine": {
        "vcpus": null,
        "ram_gb": null,
        "disk_gb": null
      },
      "mismatch": [],
      "disk_unallocated": false
    },
    "live_status": null,
    "sync_halt": null
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

Cloud volumes ​

List volumes ​

Every storage volume InfraNest tracks in the organization, a page at a time, with the server it is attached to. Filter with search, attached, unattached, server_id, status, tag or credential, and sort with sort and dir.

GET/organizations/{organization}/cloud-volumes
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-volumes" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-volumes" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-volumes', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-volumes",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-volumes', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-volumes", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "current_page": 1,
  "data": [
    {
      "id": 6,
      "organization_id": 1,
      "cloud_server_id": null,
      "provider": "digitalocean",
      "provider_volume_id": "vol-6",
      "name": "analytics-scratch",
      "size_gb": 300,
      "status": "available",
      "datacenter": "nyc3",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "provider_credential_id": 9,
      "price_monthly": "30.00",
      "price_source": "api",
      "price_currency": "eur",
      "delete_protection": false,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "native_delete_protection": false,
      "sync_halt": null,
      "server": null,
      "provider_credential": {
        "id": 9,
        "organization_id": 1,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging",
        "enabled": true,
        "verified_at": "2025-10-15T12:00:00.000000Z",
        "last_synced_at": "2026-01-15T11:48:00.000000Z",
        "reconnect_required_at": null,
        "refused_at": null
      },
      "tags": []
    },
    {
      "id": 5,
      "organization_id": 1,
      "cloud_server_id": 11,
      "provider": "digitalocean",
      "provider_volume_id": "vol-5",
      "name": "staging-data",
      "size_gb": 100,
      "status": "attached",
      "datacenter": "ams3",
      "deleted_at": null,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "provider_credential_id": 9,
      "price_monthly": "10.00",
      "price_source": "api",
      "price_currency": "eur",
      "delete_protection": false,
      "price_amount": null,
      "billing_interval": "monthly",
      "interval_count": 1,
      "native_delete_protection": false,
      "sync_halt": null,
      "server": {
        "id": 11,
        "name": "staging-api-01",
        "ipv4": "192.0.2.11",
        "status": "running",
        "hardware": {
          "vcpus": null,
          "ram_gb": null,
          "disk_gb": null,
          "plan": {
            "vcpus": null,
            "ram_gb": null,
            "disk_gb": null
          },
          "machine": {
            "vcpus": null,
            "ram_gb": null,
            "disk_gb": null
          },
          "mismatch": [],
          "disk_unallocated": false
        },
        "live_status": null,
        "sync_halt": null
      },
      "provider_credential": {
        "id": 9,
        "organization_id": 1,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging",
        "enabled": true,
        "verified_at": "2025-10-15T12:00:00.000000Z",
        "last_synced_at": "2026-01-15T11:48:00.000000Z",
        "reconnect_required_at": null,
        "refused_at": null
      },
      "tags": []
    }
  ],
  "first_page_url": "http://localhost/api/organizations/1/cloud-volumes?page=1",
  "from": 1,
  "last_page": 1,
  "last_page_url": "http://localhost/api/organizations/1/cloud-volumes?page=1",
  "links": [
    {
      "url": null,
      "label": "&laquo; Previous",
      "page": null,
      "active": false
    },
    {
      "url": "http://localhost/api/organizations/1/cloud-volumes?page=1",
      "label": "1",
      "page": 1,
      "active": true
    }
  ],
  "next_page_url": null,
  "path": "http://localhost/api/organizations/1/cloud-volumes",
  "per_page": 25,
  "prev_page_url": null,
  "to": 6,
  "total": 6,
  "meta": {
    "counts": {
      "total": 6,
      "attached": 4,
      "unattached": 2
    },
    "integrations": [
      {
        "id": 9,
        "provider": "digitalocean",
        "label": "DigitalOcean — Staging"
      },
      {
        "id": 1,
        "provider": "hetzner",
        "label": "Hetzner — Production"
      }
    ],
    "tags": []
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Get a volume ​

One volume with its server, tags, what its provider allows and the provider’s size limits where known.

GET/organizations/{organization}/cloud-volumes/{cloudVolume}
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

cloudVolumeintegerrequired

The cloud volume's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/cloud-volumes/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/cloud-volumes/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/cloud-volumes/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/cloud-volumes/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/cloud-volumes/1', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/cloud-volumes/1", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "id": 1,
  "organization_id": 1,
  "cloud_server_id": 4,
  "provider": "hetzner",
  "provider_volume_id": "vol-1",
  "name": "postgres-data",
  "size_gb": 100,
  "status": "attached",
  "datacenter": "hel1-dc2",
  "deleted_at": null,
  "created_at": "2026-01-15T12:00:00.000000Z",
  "updated_at": "2026-01-15T12:00:00.000000Z",
  "provider_credential_id": 1,
  "price_monthly": "4.80",
  "price_source": "api",
  "price_currency": "eur",
  "delete_protection": false,
  "price_amount": null,
  "billing_interval": "monthly",
  "interval_count": 1,
  "native_delete_protection": false,
  "sync_halt": null,
  "server": {
    "id": 4,
    "name": "db-01",
    "ipv4": "198.51.100.30",
    "status": "running",
    "hardware": {
      "vcpus": null,
      "ram_gb": null,
      "disk_gb": null,
      "plan": {
        "vcpus": null,
        "ram_gb": null,
        "disk_gb": null
      },
      "machine": {
        "vcpus": null,
        "ram_gb": null,
        "disk_gb": null
      },
      "mismatch": [],
      "disk_unallocated": false
    },
    "live_status": null,
    "sync_halt": null
  },
  "tags": [],
  "provider_credential": {
    "id": 1,
    "organization_id": 1,
    "provider": "hetzner",
    "label": "Hetzner — Production",
    "verified_at": "2025-10-15T12:00:00.000000Z",
    "created_at": "2026-01-15T12:00:00.000000Z",
    "updated_at": "2026-01-15T12:00:00.000000Z",
    "enabled": true,
    "enabled_capabilities": null,
    "disabled_capabilities": null,
    "error_email_enabled": true,
    "disabled_operations": null,
    "alerts_muted_until": null,
    "spending_capacity": null,
    "spending_checked_at": null,
    "scope_check": null,
    "scope_checked_at": null,
    "removing_at": null,
    "last_synced_at": "2026-01-15T11:48:00.000000Z",
    "reconnect_required_at": null,
    "account_identity": null,
    "refused_at": null,
    "refusal_checked_at": null
  },
  "capabilities": {
    "native_delete_protection": true,
    "server_destroy": true,
    "server_destroy_is_cancellation": false,
    "server_create": true,
    "server_rename": true,
    "console": true,
    "snapshots": true,
    "backups": true,
    "isos": true,
    "rescue": true,
    "placement_groups": true,
    "public_network_toggle": true,
    "scheduled_backups": true,
    "private_networks": true,
    "private_network_attach": true,
    "network_join_on_create": false,
    "network_attach_ip_choice": true,
    "private_network_unfiltered": true,
    "floating_ips": true,
    "networks_creatable": true,
    "network_cidr": true,
    "network_subnets": true,
    "network_routes": true,
    "network_rename": true,
    "network_ip_range_extendable": true,
    "firewalls_creatable": true,
    "firewall_multi_server": true,
    "firewall_renamable": true,
    "firewall_outbound": true,
    "firewall_ipv6": true,
    "firewall_dynamic_ip": true,
    "server_firewall": false,
    "load_balancers_creatable": true,
    "load_balancer_rename": true,
    "load_balancer_algorithm": true,
    "load_balancer_services": true,
    "load_balancer_targets": true,
    "volumes_creatable": true,
    "volume_resize": true,
    "volume_rename": true,
    "volume_native_delete_protection": true,
    "network_native_delete_protection": true,
    "user_data": true,
    "install_flavour": false,
    "images_per_plan": false,
    "metrics": true,
    "metrics_disk_throughput": true,
    "rdns_subnet": true,
    "rdns_address_list": false,
    "reverse_dns": true,
    "snapshot_description": true,
    "snapshot_protection": true
  },
  "size_limits": {
    "min_gb": 10,
    "max_gb": 10240
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

Connect requests ​

List connect requests ​

The 20 most recent links you created to ask someone else to connect a provider account, newest first, with who requested each one. Filter with provider or kind; the response also gives how many days a new link stays valid.

GET/organizations/{organization}/connect-requests
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

Request

sh
curl "https://api.infranest.io/api/organizations/42/connect-requests" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/connect-requests" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/connect-requests', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/connect-requests",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/connect-requests', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/connect-requests", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "data": [],
  "ttl_days": 3
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited

Endpoints ​

Get an address’s monitor ​

What the monitor on this address knows: its status, 30-day uptime, response time, the certificate each probe location receives and where its alerts go. monitor is null when nothing watches the address.

GET/organizations/{organization}/endpoints/{endpoint}/monitor
Scope monitoring.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

endpointintegerrequired

The endpoint's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/endpoints/1/monitor" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/endpoints/1/monitor" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/endpoints/1/monitor', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/endpoints/1/monitor",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/endpoints/1/monitor', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/endpoints/1/monitor", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "endpoint": {
    "id": 1,
    "host": "northwind.com",
    "port": 443,
    "proxied": true
  },
  "monitor": {
    "monitor": {
      "id": 1,
      "name": "Marketing site",
      "type": "http",
      "enabled": true
    },
    "status": "up",
    "last_checked_at": "2026-01-15T11:58:00+00:00",
    "uptime_30d": 100,
    "response_ms": 179,
    "chain_status": null,
    "locations": [
      {
        "probe_id": null,
        "name": null,
        "region": null,
        "country_code": null,
        "status": "up",
        "response_ms": 180,
        "checked_at": "2026-01-15T12:00:00+00:00",
        "fingerprint": null,
        "certificate": null
      }
    ],
    "alerts": {
      "channels": [
        {
          "id": 1,
          "name": "Ops team — email",
          "type": "email"
        },
        {
          "id": 2,
          "name": "On-call — critical only",
          "type": "email"
        }
      ],
      "people": [
        {
          "id": 2,
          "name": "Sam Okoye"
        },
        {
          "id": 3,
          "name": "Priya Raghunathan"
        }
      ],
      "reaches_anyone": true
    },
    "findings": [],
    "summary": {
      "status": "up",
      "uptime_30d": 100,
      "locations": 1,
      "locations_agree": true
    }
  }
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the monitoring.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "monitoring.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Track an address again ​

Brings an untracked address back so it is checked and shown again. Its certificates and monitor were never changed.

POST/organizations/{organization}/endpoints/{endpointId}/retrack
Scope cloud.writeChanges data
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

endpointIdintegerrequired

The endpoint id's ID.

Request

sh
curl -X POST "https://api.infranest.io/api/organizations/42/endpoints/1/retrack" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/endpoints/1/retrack" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/endpoints/1/retrack', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.post(
    "https://api.infranest.io/api/organizations/42/endpoints/1/retrack",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/endpoints/1/retrack', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/endpoints/1/retrack", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "endpoint_id": 1,
  "untracked_at": null
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.write scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.write",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "idempotency_in_progress",
  "message": "A request with this Idempotency-Key is still being handled.",
  "hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "validation_failed",
  "message": "The name field is required.",
  "hint": "Fix the fields listed in \"errors\" and send the request again.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#validation_failed",
  "errors": {
    "name": [
      "The name field is required."
    ]
  },
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited

Firewall templates ​

List firewall templates ​

The built-in firewall templates and the custom templates your organization has saved, with their rules.

GET/organizations/{organization}/firewall-templates
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

Request

sh
curl "https://api.infranest.io/api/organizations/42/firewall-templates" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/firewall-templates" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/firewall-templates', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/firewall-templates",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/firewall-templates', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/firewall-templates", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "builtin": [
    {
      "id": null,
      "slug": "web-server",
      "name": "Web Server",
      "description": "For a public website or app. Opens HTTP (80), HTTPS (443) and HTTP/3 over QUIC (UDP 443) to everyone. Add SSH restricted to your own IP separately for management.",
      "is_builtin": true,
      "rules": [
        {
          "description": "HTTP",
          "direction": "in",
          "protocol": "tcp",
          "port": "80",
          "ips": [
            "0.0.0.0/0",
            "::/0"
          ]
        },
        {
          "description": "HTTPS",
          "direction": "in",
          "protocol": "tcp",
          "port": "443",
          "ips": [
            "0.0.0.0/0",
            "::/0"
          ]
        }
      ]
    },
    {
      "id": null,
      "slug": "mail-server",
      "name": "Mail Server",
      "description": "For a self-hosted mail server. Opens SMTP (25), submission (587), SMTPS (465) for delivery and sending, plus IMAP/IMAPS (143/993) and POP3/POP3S (110/995) for clients. Open to everyone.",
      "is_builtin": true,
      "rules": [
        {
          "description": "SMTP",
          "direction": "in",
          "protocol": "tcp",
          "port": "25",
          "ips": [
            "0.0.0.0/0",
            "::/0"
          ]
        },
        {
          "description": "Submission",
          "direction": "in",
          "protocol": "tcp",
          "port": "587",
          "ips": [
            "0.0.0.0/0",
            "::/0"
          ]
        }
      ]
    }
  ],
  "custom": [
    {
      "id": 1,
      "organization_id": 1,
      "name": "Web server (80/443)",
      "description": "Allow HTTP and HTTPS from anywhere, plus SSH from the office network.",
      "slug": null,
      "is_builtin": false,
      "created_at": "2026-01-15T12:00:00.000000Z",
      "updated_at": "2026-01-15T12:00:00.000000Z",
      "deleted_at": null,
      "purge_after": null,
      "purge_reminder_sent_at": null,
      "deleted_by_id": null,
      "deleted_by_label": null,
      "deletion_reason": null,
      "rules": [
        {
          "id": 1,
          "firewall_template_id": 1,
          "description": "HTTP",
          "direction": "in",
          "protocol": "tcp",
          "port": "80",
          "ips": [
            "0.0.0.0/0",
            "::/0"
          ],
          "created_at": "2026-01-15T12:00:00.000000Z",
          "updated_at": "2026-01-15T12:00:00.000000Z"
        },
        {
          "id": 2,
          "firewall_template_id": 1,
          "description": "HTTPS",
          "direction": "in",
          "protocol": "tcp",
          "port": "443",
          "ips": [
            "0.0.0.0/0",
            "::/0"
          ],
          "created_at": "2026-01-15T12:00:00.000000Z",
          "updated_at": "2026-01-15T12:00:00.000000Z"
        }
      ]
    }
  ]
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited


Preview a firewall template ​

The rules a template would add to the given firewall, alongside how many rules the firewall has now. templateKey is a built-in template’s slug or a custom template’s id; nothing is changed.

GET/organizations/{organization}/firewall-templates/{templateKey}/preview/{cloudFirewall}
Scope cloud.readRead only
Authorizationheader
Authorizationstringrequired

Bearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.

Path parameters
organizationintegerrequired

Your organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.

templateKeyintegerrequired

The template key's ID.

cloudFirewallintegerrequired

The cloud firewall's ID.

Request

sh
curl "https://api.infranest.io/api/organizations/42/firewall-templates/1/preview/1" \
  -H "Authorization: Bearer $INFRANEST_TOKEN" \
  -H "Accept: application/json"
powershell
$headers = @{
  Authorization = "Bearer $env:INFRANEST_TOKEN"
  Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/firewall-templates/1/preview/1" -Headers $headers
php
<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/firewall-templates/1/preview/1', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

echo $response->getBody();
python
import os

import requests

response = requests.get(
    "https://api.infranest.io/api/organizations/42/firewall-templates/1/preview/1",
    headers={
        "Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
        "Accept": "application/json",
    },
)
response.raise_for_status()
print(response.json())
js
const response = await fetch('https://api.infranest.io/api/organizations/42/firewall-templates/1/preview/1', {
  headers: {
    Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
    Accept: 'application/json',
  },
})
console.log(response.status, await response.text())
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/firewall-templates/1/preview/1", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
	req.Header.Set("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(out))
}

Response

json
{
  "rules": [
    {
      "description": "HTTP",
      "direction": "in",
      "protocol": "tcp",
      "port": "80",
      "source_ips": [
        "0.0.0.0/0",
        "::/0"
      ],
      "destination_ips": []
    },
    {
      "description": "HTTPS",
      "direction": "in",
      "protocol": "tcp",
      "port": "443",
      "source_ips": [
        "0.0.0.0/0",
        "::/0"
      ],
      "destination_ips": []
    }
  ],
  "current_count": 3
}
json
{
  "code": "unauthenticated",
  "message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
  "hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#unauthenticated",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "scope_missing",
  "message": "This API token does not have the cloud.read scope.",
  "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#scope_missing",
  "required": "cloud.read",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "not_found",
  "message": "Nothing exists at this address, or you cannot see it.",
  "hint": "Check the IDs in the address. A resource in another organization answers as not found.",
  "retryable": false,
  "docs_url": "https://developers.infranest.io/errors#not_found",
  "reference": "k3j9x0b2qa"
}
json
{
  "code": "rate_limited",
  "message": "This token made more than 300 requests in a minute.",
  "hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
  "retryable": true,
  "docs_url": "https://developers.infranest.io/errors#rate_limited",
  "limit_key": "api_requests_per_minute",
  "limit": 300,
  "retry_after": 12,
  "reference": "k3j9x0b2qa"
}

401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited