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.
Cloud firewalls 3 · Cloud load balancers 2 · Cloud networks 2 · Cloud primary IPs 1 · Cloud servers 34 · Cloud snapshots 2 · Cloud volumes 2 · Connect requests 1 · Endpoints 2 · Firewall templates 2
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.
/organizations/{organization}/cloud-firewallscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-firewalls" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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": "« 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
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-firewalls/{cloudFirewall}cloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudFirewallintegerrequiredThe cloud firewall's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-firewalls/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-firewalls/{cloudFirewall}/driftcloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudFirewallintegerrequiredThe cloud firewall's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-firewalls/1/drift" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-load-balancerscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-load-balancers" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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": "« 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": []
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-load-balancers/{cloudLoadBalancer}cloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudLoadBalancerintegerrequiredThe cloud load balancer's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-load-balancers/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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": []
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-networkscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-networks" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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": []
}
]
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-networks/{cloudNetwork}cloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudNetworkintegerrequiredThe cloud network's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-networks/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-primary-ipscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-primary-ips" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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"
}
]
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-serverscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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": "« 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"
]
}
]
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}cloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}cloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Bodyapplication/json
providerstring, nullableoptionalprovider_server_idstring, nullableoptionalMust not be greater than 255 characters.
namestringoptionalMust not be greater than 255 characters.
statusstringoptionalOne of: running, stopped, starting, stopping, rebuilding, migrating, provisioning, error, unknown
server_typestring, nullableoptionalMust not be greater than 100 characters.
imagestring, nullableoptionalMust not be greater than 100 characters.
ipv4string, nullableoptionalMust not be greater than 45 characters.
ipv6string, nullableoptionalMust not be greater than 45 characters.
datacenterstring, nullableoptionalMust not be greater than 100 characters.
provisioned_atstring, nullableoptionalMust be a valid date.
metaobjectoptionalRequest
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"}'$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
// 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();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())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())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
{
"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
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/addonscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/addons" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/address-referencescloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/address-references" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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"
}
]
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/agent-releasecloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-release" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/agent-snapshotcloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-snapshot" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/agent-tokenscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/agent-tokens" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
[]{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/alert-rule-overridescloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Bodyapplication/json
default_idintegeroptionalThis field is required when key is not present.
keystringoptionalThis field is required when default_id is not present.
operatorstringoptionalOne of: >, <
thresholdnumberoptionalduration_minutesstringoptionalThe widest range any kind allows; the kind's own bounds are checked once it is known.
is_activebooleanoptionalRequest
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}'$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
// 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();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())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())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
{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/alert-rulescloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/alert-rules" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/alert-rules/{alertRule}cloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
alertRuleintegerrequiredThe alert rule's ID.
Bodyapplication/json
operatorstringoptionalOne of: >, <
thresholdnumberoptionalduration_minutesstringoptionalThe widest range any kind allows; the kind's own bounds are checked once it is known.
is_activebooleanoptionalRequest
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}'$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
// 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();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())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())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
{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/alert-rules/{alertRule}cloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
alertRuleintegerrequiredThe alert rule's ID.
Request
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"$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
// 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();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)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())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
{
"message": "Deleted."
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/attentioncloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/attention" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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": []
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/backup-pricingcloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Bodyapplication/json
backup_price_monthlynumber, nullableoptionalMust be at least 0. Must not be greater than 9999999.99.
Request
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}'$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
// 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();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())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())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
{
"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
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/backupscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/backups" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}
]
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/container-namescloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Bodyapplication/json
container_idstringrequiredMust match the regex /\A[0-9a-f]{12,64}\z/.
display_namestringrequiredMust match the regex /\A[^\p{C}]+\z/u. Must not be greater than 100 characters.
Request
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"}'$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
// 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();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())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())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
{
"container_names": [
{
"container_id": "3f2a9c1b7d4e",
"display_name": "web"
}
]
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/container-namescloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Bodyapplication/json
container_idstringrequiredMust match the regex /\A[0-9a-f]{12,64}\z/.
Request
curl -X DELETE "https://api.infranest.io/api/organizations/42/cloud-servers/1/container-names" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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)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())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
{
"container_names": []
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/firewallcloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/firewall" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/ignored-unitscloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
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"}'$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
// 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();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())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())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
{
"ignored_units": [
{
"unit": "snapd.service",
"ignored_at": "2026-01-15T12:00:00+00:00",
"ignored_by": "Alex Rivera"
}
]
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/ignored-unitscloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl -X DELETE "https://api.infranest.io/api/organizations/42/cloud-servers/1/ignored-units" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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)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())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
{
"ignored_units": []
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/imagescloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/images" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/isoscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/isos" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/metric-seriescloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Query parameters
metricsstringoptionalComma-separated metrics. Default cpu_percent,memory_percent,worst_mount_percent,load_1.
rangestringoptionalA fixed window: live, h1, h12, h24, d7 or d30. Default h24.
fromstringoptionalStart of your own window, ISO 8601, instead of range.
tostringoptionalEnd of your own window, ISO 8601; default now.
resolutionstringoptionalraw or hour; default: raw when the samples still cover the window.
per_pageintegeroptionalPoints per page, 1 to 10,000. Default 10,000.
pageintegeroptionalPage number, from 1.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/metric-series" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/metricscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/metrics" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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"
]
]
}
}
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/monitoringcloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl -X POST "https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"monitoring_enabled": true,
"monitoring_enabled_at": null,
"usage": 11,
"limit": null
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/monitoringcloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl -X DELETE "https://api.infranest.io/api/organizations/42/cloud-servers/1/monitoring" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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)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())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
{
"monitoring_enabled": false,
"monitoring_enabled_at": null,
"usage": 10,
"limit": null
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/pricingcloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
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"}'$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
// 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();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())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())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
{
"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
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/provider-actionscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/1/provider-actions" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/reset-pricingcloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl -X POST "https://api.infranest.io/api/organizations/42/cloud-servers/1/reset-pricing" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/snoozecloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Bodyapplication/json
minutesintegeroptionalCapped 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
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}'$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
// 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();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())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())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
{
"maintenance_window_id": 5,
"until": "2026-01-15T13:00:00+00:00"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/snoozecloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl -X DELETE "https://api.infranest.io/api/organizations/42/cloud-servers/1/snooze" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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)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())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
{
"ended": 0,
"alerts_quiet_until": null
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{cloudServer}/untrackcloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudServerintegerrequiredThe cloud server's ID.
Request
curl -X POST "https://api.infranest.io/api/organizations/42/cloud-servers/1/untrack" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"message": "Server is no longer tracked."
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-servers/{serverId}/retrackcloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
serverIdintegerrequiredThe server id's ID.
Request
curl -X POST "https://api.infranest.io/api/organizations/42/cloud-servers/1/retrack" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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).
/organizations/{organization}/cloud-servers/metrics-overviewcloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-servers/metrics-overview" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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": "« 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"
}
]
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-snapshotscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-snapshots" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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": "« 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": []
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-snapshots/{cloudSnapshot}cloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudSnapshotintegerrequiredThe cloud snapshot's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-snapshots/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-volumescloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-volumes" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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": "« 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": []
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/cloud-volumes/{cloudVolume}cloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
cloudVolumeintegerrequiredThe cloud volume's ID.
Request
curl "https://api.infranest.io/api/organizations/42/cloud-volumes/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/connect-requestscloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/connect-requests" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"data": [],
"ttl_days": 3
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/endpoints/{endpoint}/monitormonitoring.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
endpointintegerrequiredThe endpoint's ID.
Request
curl "https://api.infranest.io/api/organizations/42/endpoints/1/monitor" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}
}
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/endpoints/{endpointId}/retrackcloud.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
endpointIdintegerrequiredThe endpoint id's ID.
Request
curl -X POST "https://api.infranest.io/api/organizations/42/endpoints/1/retrack" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"endpoint_id": 1,
"untracked_at": null
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/firewall-templatescloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/firewall-templates" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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"
}
]
}
]
}{
"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"
}{
"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"
}{
"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"
}{
"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.
/organizations/{organization}/firewall-templates/{templateKey}/preview/{cloudFirewall}cloud.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
templateKeyintegerrequiredThe template key's ID.
cloudFirewallintegerrequiredThe cloud firewall's ID.
Request
curl "https://api.infranest.io/api/organizations/42/firewall-templates/1/preview/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$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
// 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();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())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())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
{
"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
}{
"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"
}{
"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"
}{
"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"
}{
"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