Skip to content

Servers

A server is a virtual machine in one of your projects. Its id is a lowercase hexadecimal string, such as "774736". This page covers reading servers and changing their hostname, reverse DNS and cancellation.

Operations that run on the server, such as power, reinstall and snapshots, are actions. Ordering, upgrading and extra bandwidth are orders. Firewall groups are attached on the Firewalls page.

Endpoints

Endpoint What it does
GET /projects/{slug}/servers/ List servers
POST /projects/{slug}/servers/ Order a server
GET /projects/{slug}/servers/{id}/ Get a server
PATCH /projects/{slug}/servers/{id}/ Rename a server
GET /projects/{slug}/servers/{id}/reverse-dns/ List reverse DNS names
PUT /projects/{slug}/servers/{id}/reverse-dns/{address}/ Set a reverse DNS name
DELETE /projects/{slug}/servers/{id}/reverse-dns/{address}/ Clear a reverse DNS name
GET /projects/{slug}/servers/{id}/upgrade-options/ List upgrade options
POST /projects/{slug}/servers/{id}/upgrade/ Upgrade a server
POST /projects/{slug}/servers/{id}/bandwidth/ Buy extra bandwidth
POST /projects/{slug}/servers/{id}/cancel/ Cancel a server

The server object

{
  "id": "774736",
  "hostname": "web-01",
  "status": "running",
  "pending_changes": false,
  "location": {"code": "AMS", "city": "Amsterdam", "country_code": "NL"},
  "image": {"name": "almalinux10", "display_name": "AlmaLinux 10"},
  "plan": {"name": "Cloud VPS 2x4", "category": "Compute", "cpu_cores": 2, "ram_mb": 4096, "disk_gb": 80, "boot_disk_gb": 0},
  "network": {
    "ipv4": [
      {"address": "203.0.113.10", "primary": true, "netmask": "255.255.255.0", "gateway": "203.0.113.1"},
      {"address": "203.0.113.24", "primary": false, "netmask": "255.255.255.0", "gateway": null}
    ],
    "ipv6": [{"subnet": "2001:db8:2:f342::/64"}],
    "private_network": {"eligible": true, "enabled": false}
  },
  "bandwidth": {
    "pooled": true,
    "allocated_gb": 1000, "extra_gb": 0, "used_gb": 12,
    "pool": {"allocated_gb": 5000, "extra_gb": 0, "used_gb": 301}
  },
  "firewall_groups": [12],
  "ssh_keys": [3731],
  "iso": null,
  "has_user_data": false,
  "billing": {
    "service_id": 188060, "status": "Active", "billing_cycle": "monthly",
    "next_due_date": "2026-11-13", "recurring_amount": "12.00", "currency": "USD",
    "upgradeable_to": [41, 42]
  },
  "created_at": "2026-10-13T12:58:59Z"
}
Field Type Description
id string The server's id, lowercase hexadecimal.
hostname string or null The server's name.
status string running, stopped or suspended.
pending_changes boolean The server has changes, such as a new plan, that its next reboot through the API applies. A reboot from inside the server doesn't apply them.
location object code, the location code that orders use, such as AMS; city; and country_code, ISO 3166-1 alpha-2 in capitals. Each is null when unknown.
image object The operating system: name, which reinstall takes, and display_name. Either can be null when unknown.
plan object name, category, cpu_cores, ram_mb, disk_gb and boot_disk_gb. Each can be null when unknown.
network.ipv4 array The server's IPv4 addresses, the primary one first. Each has address, primary, netmask, which can be null, and gateway, which only the primary address has.
network.ipv6 array The IPv6 subnets routed to the server, as {"subnet": "2001:db8::/64"}. Empty until you enable IPv6.
network.private_network object or null eligible: the server can join the private network; enabled: it has. Either can be null when unknown.
bandwidth object or null This month's traffic: allocated_gb, extra_gb bought on top, and used_gb, each an integer or null when unknown. pooled servers share an allowance with your other servers in the location, and pool has its totals, which can be null too; pool itself is null when the server is not pooled.
firewall_groups array or null The ids of the firewall groups attached to the server. null when they couldn't be read just now: never read null as "no firewall".
ssh_keys array The ids of the project's SSH keys set on the server.
iso object or null The mounted ISO, as {"id", "name"}, where name can be null; or null when none is mounted.
has_user_data boolean The server was installed with cloud-init user data.
billing object or null service_id; status as billing reports it, such as Active; billing_cycle, such as monthly or semiannually; next_due_date; recurring_amount and currency; and upgradeable_to, the product ids an upgrade can move it to. status, billing_cycle, next_due_date and recurring_amount can be null. The whole object is null when the server has no billing service, or billing couldn't be read just now.
created_at string or null When the server was created.

When billing or the firewall can't be read, the server is still returned, with that field null.

In lists

Lists return a summary of each server. Get the server for the rest. hostname, ipv4_primary and plan.name can be null, and so can each of location's fields.

{
  "id": "774736",
  "hostname": "web-01",
  "status": "running",
  "ipv4_primary": "203.0.113.10",
  "location": {"code": "AMS", "city": "Amsterdam", "country_code": "NL"},
  "plan": {"name": "Cloud VPS 2x4"}
}

Reading and renaming

List servers

GET /projects/{slug}/servers/

Any member · Read-only keys: yes · Returns 200 ServerSummary[]

The project's servers, as summaries.

curl "https://console.hosthatch.com/api/v1/projects/acme/servers/" \
  -H "Authorization: Bearer $HOSTHATCH_API_KEY"

Get a server

GET /projects/{slug}/servers/{id}/

Any member · Read-only keys: yes · Returns 200 Server

One server, with everything in the server object.

Rename a server

PATCH /projects/{slug}/servers/{id}/

Any member · Read-only keys: no · Returns 200 Server

Change the server's hostname, the only property of a server that can change this way. The answer is the updated server.

curl -X PATCH "https://console.hosthatch.com/api/v1/projects/acme/servers/774736/" \
  -H "Authorization: Bearer $HOSTHATCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"hostname": "web-01.example.com"}'

A hostname is 2 to 64 characters. It is one or more labels separated by dots, and each label has 1 to 63 letters, digits and hyphens, and starts and ends with a letter or a digit. A body without hostname changes nothing.

Reverse DNS

Reverse DNS maps an address back to a name, which mail servers and some other services check. Set a matching forward record (A or AAAA) for the name at your DNS provider too.

List reverse DNS names

GET /projects/{slug}/servers/{id}/reverse-dns/

Any member · Read-only keys: yes · Returns 200 ReverseDns[]

The reverse DNS name of each of the server's IPv4 addresses. ptr is null where none is set.

{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {"address": "203.0.113.10", "ptr": "web-01.example.com"},
    {"address": "203.0.113.24", "ptr": null}
  ]
}

Set a reverse DNS name

PUT /projects/{slug}/servers/{id}/reverse-dns/{address}/

Any member · Read-only keys: no · Returns 200 ReverseDns

Set the name of one of the server's addresses: one of its IPv4 addresses, or any address inside one of its IPv6 subnets. Another address answers 404 not_found.

curl -X PUT "https://console.hosthatch.com/api/v1/projects/acme/servers/774736/reverse-dns/203.0.113.10/" \
  -H "Authorization: Bearer $HOSTHATCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ptr": "web-01.example.com"}'
{"address": "203.0.113.10", "ptr": "web-01.example.com"}

ptr is a domain name of up to 255 characters, in ASCII, without a dot at the end. Each label has letters, digits and hyphens, and doesn't start or end with a hyphen.

Clear a reverse DNS name

DELETE /projects/{slug}/servers/{id}/reverse-dns/{address}/

Any member · Read-only keys: no · Returns 204

Remove the name of one of the server's addresses.

When the reverse DNS service is unavailable, these endpoints answer 503 reverse_dns_unavailable with Retry-After: 300.

Cancellation

Cancel a server

POST /projects/{slug}/servers/{id}/cancel/

Admin or owner · Read-only keys: no · Returns 200 Cancellation

Ask for the server to be cancelled.

Field Type Description
when string end_of_term: the server runs until the end of the period you paid for, then it is deleted. immediate: it is deleted now, with everything on it.
reason string Why, in up to 1000 characters. Required for end_of_term.
curl -X POST "https://console.hosthatch.com/api/v1/projects/acme/servers/774736/cancel/" \
  -H "Authorization: Bearer $HOSTHATCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"when": "end_of_term", "reason": "Moving to a bigger plan"}'
{"status": "cancellation_requested", "when": "end_of_term"}

A server keeps one cancellation request, so the request is safe to repeat as it is. Sending the same one again answers 200 and changes nothing, and it needs no Idempotency-Key. A request of the other kind answers 409 conflict. Once an immediate cancellation has been carried out, the server is gone and a repeat answers 404.

A 502 upstream_error means the request may not have been recorded: send the same request again.

Errors

Status Code When
400 validation_error A field is invalid.
403 insufficient_role Cancelling needs the admin or owner role.
403 read_only_key A change with a read-only key.
403 billing_account_required The project's owner has no billing account.
403 project_not_ready The project is still being set up.
404 not_found No such server or address in the project.
409 conflict A cancellation of the other kind is requested, or the server's billing service can't be matched: contact support.
502 upstream_error A system behind the API failed.
503 upstream_unavailable A system behind the API is unavailable for now.
503 reverse_dns_unavailable The reverse DNS service is unavailable for now.