Hetzner API Rust SDK
current version: 1.0.0
A Rust SDK for Hetzner APIs with a domain-oriented structure and typed error handling.
Documentation
- Full docs:
docs/COMPREHENSIVE_DOCUMENTATION.md - API reference:
docs/API_REFERENCE.md - Project-owned OpenAPI:
openapi.json
API Coverage
cloud (openapi-backed)
- Full Hetzner Cloud OpenAPI operation coverage via generated methods on
cloud() - Hand-written typed surfaces for:
-
servers.list -
servers.get -
servers.create(typed response:server,action,next_actions,root_password) -
actions.list(ID-filtered) -
actions.get
dns (legacy)
- GetAllZones
- GetAllRecords
- CreateRecord
- GetRecord
- UpdateRecord
- DeleteRecord
- CreateZone
- GetZone
- UpdateZone
- DeleteZone
Deprecation Notice
The legacy DNS API surface is now deprecated.
- Deprecated style: direct DNS methods on
HetznerClient(for exampleclient.get_all_zones()). - Preferred style: domain APIs (for example
client.dns().list_zones()).
Compatibility wrappers remain available for now and are marked deprecated in code.
Installation
[]
= "0.3.1"
= { = "1", = ["macros", "rt-multi-thread"] }
Quick Start
use HetznerClient;
async
Cloud Servers Example
use ;
async
Cloud Actions Example
use ;
async
Full OpenAPI Operation Example
All operations from hetzner-cloud-openapi.json are generated as methods on CloudApi using their operationId.
use HetznerClient;
async
API Facades
The SDK now exposes direct API groups for the areas you requested:
client.dns()legacy DNS API (records/zones)client.cloud().servers_api()full Servers API (CRUD/actions/metrics)client.cloud().domains()Domain/Zone API (zones/rrsets)client.cloud().private_networks()Private Network APIclient.cloud().load_balancers()Load Balancer APIclient.cloud().storage()Storage API (volumes/images/isos)- plus complete raw OpenAPI methods via
client.cloud().<operation_id>(...)
Cloud API Example Request
Since a new project commonly has no servers yet, this is the expected empty list shape.
Example Request
Example Response
Authentication
All requests to the Hetzner Cloud API must be authenticated with an API token.
Use this header:
Authorization: Bearer tbzcPCFQOYdvw5udQKYpaGeeT32GvUix2Iw7T6z0ZVy22c5EnmTVCxgkYOz8b4p5
To create a token: Hetzner Console -> Project -> Security -> API Tokens.
Error Handling
The SDK returns typed errors (HetznerError) and preserves API error payload details.
Hetzner API error payload shape:
code: machine-parsable error identifiermessage: human-readable descriptiondetails: optional object with code-specific fields
Example Error Payload
Common Error Codes
| Status | Code | Description |
|---|---|---|
| 400 | json_error |
Invalid JSON input in request |
| 401 | unauthorized |
Invalid or unknown token |
| 401 | token_readonly |
Token only allows GET requests |
| 403 | forbidden |
Insufficient permissions |
| 403 | maintenance |
Operation blocked by maintenance |
| 403 | resource_limit_exceeded |
Account/project resource limit exceeded |
| 404 | not_found |
Entity not found |
| 405 | method_not_allowed |
HTTP method not allowed |
| 409 | uniqueness_error |
Uniqueness constraint violation |
| 409 | conflict |
Resource changed during request |
| 410 | deprecated_api_endpoint |
Endpoint functionality removed |
| 412 | resource_unavailable |
Requested resource unavailable |
| 422 | invalid_input |
Input parsing/validation failed |
| 422 | service_error |
Internal service-level error |
| 422 | unsupported_error |
Action unsupported by resource |
| 423 | locked |
Resource locked by running action |
| 423 | protected |
Action protected for resource |
| 429 | rate_limit_exceeded |
Request limit exceeded |
| 500 | server_error |
API backend error |
| 503 | unavailable |
Service/product unavailable |
| 504 | timeout |
Request timeout |
Actions
Actions are asynchronous tasks that may be returned when mutating resources.
- Wait until action state is
successorerror. - Avoid aggressive polling to reduce rate limit pressure.
- Failed actions include additional error context.
Labels
Labels are key/value pairs on resources.
- Keys: optional DNS-like prefix + required name segment (
prefix/name). - Values: up to 63 chars, empty or alphanumeric-bounded with
-,_,.allowed. - Prefix
hetzner.cloud/is reserved.
Example Labels
Label Selector
Supported selectors include:
k==vork=vk!=vk!kk in (v1,v2,v3)k notin (v1,v2,v3)
Examples:
env=production,type!=database
env in (testing,staging)
!type
Pagination
List endpoints can support page and per_page (default 25, usually max 50).
Responses can include:
meta.paginationin JSONLinkheader withprev,next,last
Example Pagination Payload
Rate Limiting
All requests are rate limited.
Headers:
RateLimit-LimitRateLimit-RemainingRateLimit-Reset(UNIX timestamp)
Default limit is 3600 requests/hour per project, with gradual refill.
Server Metadata
In-server metadata endpoint:
http://169.254.169.254/hetzner/v1/metadata
Available keys include:
hostnameinstance-idpublic-ipv4private-networksavailability-zoneregion
Sorting
Some list endpoints support repeated sort query params.
Examples:
https://api.hetzner.cloud/v1/actions?sort=status
https://api.hetzner.cloud/v1/actions?sort=status:asc
https://api.hetzner.cloud/v1/actions?sort=status:desc
https://api.hetzner.cloud/v1/actions?sort=status:asc&sort=command:desc
Structure
Current crate structure:
client: transport, auth, request lifecycleerror: typed SDK errors and API error envelopestypes: shared response/resource modelsapi::dns: DNS domain operationsapi::cloud: Cloud domain operations (serversfirst)api::cloud::enums: OpenAPI-derived enums for server status/sort and action statusapi::cloud::generated_ops: full OpenAPI-generated operation methods
This layout is intended to support additional Hetzner domains without flattening everything into one module.