This is the official documentation for the Hetzner API.
The Hetzner API operates over HTTPS and uses JSON as its data format. The API is a RESTful API and utilizes HTTP methods and HTTP status codes to specify requests and responses.
If you are developing an open-source project that supports or intends to add support for Hetzner APIs, you may be eligible for a free one-time credit of up to € 50 / $ 50 on your account. Please contact us via the support page on your Console and let us know the following:
To get started using the API you first need an API token. Sign in into the Hetzner Console choose a Project, go to Security
→ API Tokens
, and generate a new token. Make sure to copy the token because it won’t be shown to you again. A token is bound to a Project, to interact with the API of another Project you have to create a new token inside the Project. Let’s say your new token is LRK9DAWQ1ZAEFSrCNEEzLCUwhYX1U3g7wMg4dTlkkDC96fyDuyJ39nVbVjCKSDfj
.
You’re now ready to do your first request against the API. To get a list of all Storage Boxes in your Project, issue the example request on the right side using curl.
Make sure to replace the token in the example command with the token you have just created. Since your Project probably does not contain any Storage Boxes yet, the example response will look like the response on the right side. We will almost always provide a resource root like storage_boxes
inside the example response. A response can also contain a meta
object with information like Pagination.
curl -H "Authorization: Bearer LRK9DAWQ1ZAEFSrCNEEzLCUwhYX1U3g7wMg4dTlkkDC96fyDuyJ39nVbVjCKSDfj" \
https://api.hetzner.com/v1/storage_boxes
{
"storage_boxes": [],
"meta": {
"pagination": {
"page": 1,
"per_page": 25,
"previous_page": null,
"next_page": null,
"last_page": 1,
"total_entries": 0
}
}
}
All requests to the Hetzner API must be authenticated via a API token. Include your secret API token in every request you send to the API with the Authorization
HTTP header.
To create a new API token for your Project, switch into the Hetzner Console choose a Project, go to Security
→ API Tokens
, and generate a new token.
Authorization: Bearer LRK9DAWQ1ZAEFSrCNEEzLCUwhYX1U3g7wMg4dTlkkDC96fyDuyJ39nVbVjCKSDfj
Errors are indicated by HTTP status codes. Further, the response of the request which generated the error contains an error code, an error message, and, optionally, error details. The schema of the error details object depends on the error code.
The error response contains the following keys:
Keys | Meaning |
---|---|
code |
Short string indicating the type of error (machine-parsable) |
message |
Textual description on what has gone wrong |
details |
An object providing for details on the error (schema depends on code) |
Code | Description |
---|---|
forbidden |
Insufficient permissions for this request |
unauthorized |
Request was made with an invalid or unknown token |
invalid_input |
Error while parsing or processing the input |
json_error |
Invalid JSON input in your request |
locked |
The item you are trying to access is locked (there is already an Action running) |
not_found |
Entity not found |
rate_limit_exceeded |
Error when sending too many requests |
resource_limit_exceeded |
Error when exceeding the maximum quantity of a resource for an account |
resource_unavailable |
The requested resource is currently unavailable (e.g. not available for order) |
server_error |
Error within the API backend |
service_error |
Error within a service |
uniqueness_error |
One or more of the objects fields must be unique |
protected |
The Action you are trying to start is protected for this resource |
maintenance |
Cannot perform operation due to maintenance |
conflict |
The resource has changed during the request, please retry |
unsupported_error |
The corresponding resource does not support the Action |
token_readonly |
The token is only allowed to perform GET requests |
unavailable |
A service or product is currently not available |
deprecated_api_endpoint |
The request can not be answered because the API functionality was removed |
timeout |
The request could not be answered in time, please retry |
{
"error": {
"code": "invalid_input",
"message": "invalid input in field 'broken_field': is too long",
"details": {
"fields": [
{
"name": "broken_field",
"messages": ["is too long"]
}
]
}
}
}
{
"error": {
"code": "invalid_input",
"message": "invalid input in field 'broken_field': is too long",
"details": {
"fields": [
{
"name": "broken_field",
"messages": ["is too long"]
}
]
}
}
}
{
"error": {
"code": "uniqueness_error",
"message": "SSH key with the same fingerprint already exists",
"details": {
"fields": [
{
"name": "public_key"
}
]
}
}
}
{
"error": {
"code": "resource_limit_exceeded",
"message": "project limit exceeded",
"details": {
"limits": [
{
"name": "project_limit"
}
]
}
}
}
{
"error": {
"code": "deprecated_api_endpoint",
"message": "API functionality was removed",
"details": {
"announcement": "https://docs.hetzner.cloud/changelog#2023-07-20-foo-endpoint-is-deprecated"
}
}
}
Labels are key/value
pairs that can be attached to all resources.
Valid label keys have two segments: an optional prefix and name, separated by a slash (/
). The name segment is required and must be a string of 63 characters or less, beginning and ending with an alphanumeric character ([a-z0-9A-Z]
) with dashes (-
), underscores (_
), dots (.
), and alphanumerics between. The prefix is optional. If specified, the prefix must be a DNS subdomain: a series of DNS labels separated by dots (.
), not longer than 253 characters in total, followed by a slash (/
).
Valid label values must be a string of 63 characters or less and must be empty or begin and end with an alphanumeric character ([a-z0-9A-Z]
) with dashes (-
), underscores (_
), dots (.
), and alphanumerics between.
The hetzner.cloud/
prefix is reserved and cannot be used.
{
"labels": {
"environment": "development",
"service": "backend",
"example.com/my": "label",
"just-a-key": ""
}
}
For resources with labels, you can filter resources by their labels using the label selector query language.
Expression | Meaning |
---|---|
k==v / k=v |
Value of key k does equal value v |
k!=v |
Value of key k does not equal value v |
k |
Key k is present |
!k |
Key k is not present |
k in (v1,v2,v3) |
Value of key k is v1 , v2 , or v3 |
k notin (v1,v2,v3) |
Value of key k is neither v1 , nor v2 , nor v3 |
k1==v,!k2 |
Value of key k1 is v and key k2 is not present |
Returns all resources that have a env=production
label and that don't have a type=database
label:
env=production,type!=database
Returns all resources that have a env=testing
or env=staging
label:
env in (testing,staging)
Returns all resources that don't have a type
label:
!type
Responses which return multiple items support pagination. If they do support pagination, it can be controlled with following query string parameters:
page
parameter specifies the page to fetch. The number of the first page is 1.per_page
parameter specifies the number of items returned per page. The default value is 25, the maximum value is 50 except otherwise specified in the documentation.Responses contain a Link
header with pagination information.
Additionally, if the response body is JSON and the root object is an object, that object has a pagination
object inside the meta
object with pagination information:
The keys previous_page
, next_page
, last_page
, and total_entries
may be null
when on the first page, last page, or when the total number of entries is unknown.
Line breaks have been added for display purposes only and responses may only contain some of the above rel
values.
{
"storage_boxes": [...],
"meta": {
"pagination": {
"page": 2,
"per_page": 25,
"previous_page": 1,
"next_page": 3,
"last_page": 4,
"total_entries": 100
}
}
}
Link: <https://api.hetzner.com/v1/storage_boxes?page=2&per_page=5>; rel="prev",
<https://api.hetzner.com/v1/storage_boxes?page=4&per_page=5>; rel="next",
<https://api.hetzner.com/v1/storage_boxes?page=6&per_page=5>; rel="last"
All requests, whether they are authenticated or not, are subject to rate limiting. If you have reached your limit, your requests will be handled with a 429 Too Many Requests
error. Burst requests are allowed. Responses contain several headers which provide information about your current rate limit status.
RateLimit-Limit
header contains the total number of requests you can perform per hour.RateLimit-Remaining
header contains the number of requests remaining in the current rate limit time frame.RateLimit-Reset
header contains a UNIX timestamp of the point in time when your rate limit will have recovered, and you will have the full number of requests available again.The default limit is 3600 requests per hour and per Project. The number of remaining requests increases gradually. For example, when your limit is 3600 requests per hour, the number of remaining requests will increase by 1 every second.
Some responses which return multiple items support sorting. If they do support sorting the documentation states which fields can be used for sorting. You specify sorting with the sort
query string parameter. You can sort by multiple fields. You can set the sort direction by appending :asc
or :desc
to the field name. By default, ascending sorting is used.
https://api.hetzner.com/v1/storage_boxes?sort=status:asc
https://api.hetzner.com/v1/storage_boxes?sort=status:desc
https://api.hetzner.com/v1/storage_boxes?sort=status:asc&sort=command:desc
You can find all announced deprecations in our Changelog.
Storage Boxes are storage products that can be provisioned.
Returns all existing Storage Box objects.
GET /storage_boxes
Filter resources by labels. The response will only contain resources matching the label selector. For more information, see "Label Selector".
Filter resources by their name. The response will only contain the resources matching exactly the specified name.
25
Maximum number of entries returned per page. For more information, see "Pagination".
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes"
Content-Type: application/json
Status: 200
{
"storage_boxes": [
{
"id": 42,
"username": "u12345",
"status": "active",
"name": "string",
"storage_box_type": {
"id": 42,
"name": "bx11",
"description": "BX11",
"snapshot_limit": 10,
"automatic_snapshot_limit": 10,
"subaccounts_limit": 200,
"size": 1073741824,
"prices": [
{
"location": "fsn1",
"price_hourly": {
"net": "1.0000",
"gross": "1.1900"
},
"price_monthly": {
"net": "1.0000",
"gross": "1.1900"
},
"setup_fee": {
"net": "1.0000",
"gross": "1.1900"
}
}
],
"deprecation": {
"unavailable_after": "2023-09-01T00:00:00+00:00",
"announced": "2023-06-01T00:00:00+00:00"
}
},
"location": {
"id": 42,
"name": "fsn1",
"description": "Falkenstein DC Park 1",
"country": "DE",
"city": "Falkenstein",
"latitude": 50.47612,
"longitude": 12.370071,
"network_zone": "eu-central"
},
"access_settings": {
"reachable_externally": false,
"samba_enabled": false,
"ssh_enabled": false,
"webdav_enabled": false,
"zfs_enabled": false
},
"server": "u1337.your-storagebox.de",
"system": "FSN1-BX355",
"stats": {
"size": 0,
"size_data": 0,
"size_snapshots": 0
},
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
},
"protection": {
"delete": false
},
"snapshot_plan": {
"max_snapshots": 0,
"minute": null,
"hour": null,
"day_of_week": null,
"day_of_month": null
},
"created": "2016-01-30T23:55:00+00:00"
}
],
"meta": {
"pagination": {
"page": 3,
"per_page": 25,
"previous_page": 2,
"next_page": 4,
"last_page": 4,
"total_entries": 100
}
}
}
Creates a new Storage Box. Returns an Action that covers progress of creation.
POST /storage_boxes
The name or the ID of the Storage Box Type.
Unique identifier of the Location.
Name of the Resource. Must be unique per Project.
The password that will be set for this Storage Box.
User-defined labels (key/value
pairs) for the Resource.
For more information, see "Labels".
Array of SSH public keys in OpenSSH format which should be injected into the Storage Box.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"storage_box_type":"bx20","location":"fsn1","name":"my-resource","password":"string","labels":{"environment":"prod","example.com/my":"label","just-a-key":""},"ssh_keys":["ssh-rsa AAAjjk76kgf...Xt"],"access_settings":{"samba_enabled":false,"ssh_enabled":true,"webdav_enabled":false,"zfs_enabled":false,"reachable_externally":false}}' \
"https://api.hetzner.com/v1/storage_boxes"
{
"storage_box_type": "bx20",
"location": "fsn1",
"name": "my-resource",
"password": "string",
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
},
"ssh_keys": [
"ssh-rsa AAAjjk76kgf...Xt"
],
"access_settings": {
"samba_enabled": false,
"ssh_enabled": true,
"webdav_enabled": false,
"zfs_enabled": false,
"reachable_externally": false
}
}
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "create",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Returns a specific Storage Box object. The Storage Box must exist inside the Project.
GET /storage_boxes/{id}
ID of the Storage Box.
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID"
Content-Type: application/json
Status: 200
{
"storage_box": {
"id": 42,
"username": "u12345",
"status": "active",
"name": "string",
"storage_box_type": {
"id": 42,
"name": "bx11",
"description": "BX11",
"snapshot_limit": 10,
"automatic_snapshot_limit": 10,
"subaccounts_limit": 200,
"size": 1073741824,
"prices": [
{
"location": "fsn1",
"price_hourly": {
"net": "1.0000",
"gross": "1.1900"
},
"price_monthly": {
"net": "1.0000",
"gross": "1.1900"
},
"setup_fee": {
"net": "1.0000",
"gross": "1.1900"
}
}
],
"deprecation": {
"unavailable_after": "2023-09-01T00:00:00+00:00",
"announced": "2023-06-01T00:00:00+00:00"
}
},
"location": {
"id": 42,
"name": "fsn1",
"description": "Falkenstein DC Park 1",
"country": "DE",
"city": "Falkenstein",
"latitude": 50.47612,
"longitude": 12.370071,
"network_zone": "eu-central"
},
"access_settings": {
"reachable_externally": false,
"samba_enabled": false,
"ssh_enabled": false,
"webdav_enabled": false,
"zfs_enabled": false
},
"server": "u1337.your-storagebox.de",
"system": "FSN1-BX355",
"stats": {
"size": 0,
"size_data": 0,
"size_snapshots": 0
},
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
},
"protection": {
"delete": false
},
"snapshot_plan": {
"max_snapshots": 0,
"minute": null,
"hour": null,
"day_of_week": null,
"day_of_month": null
},
"created": "2016-01-30T23:55:00+00:00"
}
}
Updates a Storage Box. You can update a Storage Boxes' name and labels.
PUT /storage_boxes/{id}
ID of the Storage Box.
The Storage Boxes' name.
The Storage Boxes' labels.
curl \
-X PUT \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"string","labels":{"environment":"prod","example.com/my":"label","just-a-key":""}}' \
"https://api.hetzner.com/v1/storage_boxes/$ID"
{
"name": "string",
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
}
}
Content-Type: application/json
Status: 200
{
"storage_box": {
"id": 42,
"username": "u12345",
"status": "active",
"name": "string",
"storage_box_type": {
"id": 42,
"name": "bx11",
"description": "BX11",
"snapshot_limit": 10,
"automatic_snapshot_limit": 10,
"subaccounts_limit": 200,
"size": 1073741824,
"prices": [
{
"location": "fsn1",
"price_hourly": {
"net": "1.0000",
"gross": "1.1900"
},
"price_monthly": {
"net": "1.0000",
"gross": "1.1900"
},
"setup_fee": {
"net": "1.0000",
"gross": "1.1900"
}
}
],
"deprecation": {
"unavailable_after": "2023-09-01T00:00:00+00:00",
"announced": "2023-06-01T00:00:00+00:00"
}
},
"location": {
"id": 42,
"name": "fsn1",
"description": "Falkenstein DC Park 1",
"country": "DE",
"city": "Falkenstein",
"latitude": 50.47612,
"longitude": 12.370071,
"network_zone": "eu-central"
},
"access_settings": {
"reachable_externally": false,
"samba_enabled": false,
"ssh_enabled": false,
"webdav_enabled": false,
"zfs_enabled": false
},
"server": "u1337.your-storagebox.de",
"system": "FSN1-BX355",
"stats": {
"size": 0,
"size_data": 0,
"size_snapshots": 0
},
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
},
"protection": {
"delete": false
},
"snapshot_plan": {
"max_snapshots": 0,
"minute": null,
"hour": null,
"day_of_week": null,
"day_of_month": null
},
"created": "2016-01-30T23:55:00+00:00"
}
}
Deletes an existing Storage Box.
DELETE /storage_boxes/{id}
ID of the Storage Box.
curl \
-X DELETE \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID"
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "delete",
"status": "success",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
}
],
"error": null
}
}
Lists the (sub)folders contained in a Storage Box at the location specified by the path. Files are not part of the response.
GET /storage_boxes/{id}/folders
ID of the Storage Box.
Relative path for which the listing is to be made.
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID/folders"
Content-Type: application/json
Status: 200
{
"folders": [
"offsite-backup",
"photos"
]
}
Returns all Action objects.
GET /storage_boxes/actions
Filter the actions by ID. Can be used multiple times. The response will only contain actions matching the specified IDs.
id
id:asc
id:desc
command
command:asc
command:desc
status
status:asc
status:desc
started
started:asc
started:desc
finished
finished:asc
finished:desc
Sort actions by field and direction. Can be used multiple times. For more information, see "Sorting".
running
success
error
Filter the actions by status. Can be used multiple times. The response will only contain actions matching the specified statuses.
25
Maximum number of entries returned per page. For more information, see "Pagination".
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/actions"
Content-Type: application/json
Status: 200
{
"actions": [
{
"id": 42,
"command": "start_resource",
"status": "running",
"started": "2016-01-30T23:55:00+00:00",
"finished": "2016-01-30T23:55:00+00:00",
"progress": 100,
"resources": [
{
"id": 42,
"type": "server"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
],
"meta": {
"pagination": {
"page": 3,
"per_page": 25,
"previous_page": 2,
"next_page": 4,
"last_page": 4,
"total_entries": 100
}
}
}
Returns a specific Action object.
GET /storage_boxes/actions/{id}
ID of the Action.
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/actions/$ID"
Content-Type: application/json
Status: 200
{
"action": {
"id": 42,
"command": "start_resource",
"status": "running",
"started": "2016-01-30T23:55:00+00:00",
"finished": "2016-01-30T23:55:00+00:00",
"progress": 100,
"resources": [
{
"id": 42,
"type": "server"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
List all Actions related to a specific Storage Box.
GET /storage_boxes/{id}/actions
ID of the Storage Box.
id
id:asc
id:desc
command
command:asc
command:desc
status
status:asc
status:desc
started
started:asc
started:desc
finished
finished:asc
finished:desc
Sort actions by field and direction. Can be used multiple times. For more information, see "Sorting".
running
success
error
Filter the actions by status. Can be used multiple times. The response will only contain actions matching the specified statuses.
25
Maximum number of entries returned per page. For more information, see "Pagination".
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID/actions"
Content-Type: application/json
Status: 200
{
"actions": [
{
"id": 42,
"command": "start_resource",
"status": "running",
"started": "2016-01-30T23:55:00+00:00",
"finished": "2016-01-30T23:55:00+00:00",
"progress": 100,
"resources": [
{
"id": 42,
"type": "server"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
],
"meta": {
"pagination": {
"page": 3,
"per_page": 25,
"previous_page": 2,
"next_page": 4,
"last_page": 4,
"total_entries": 100
}
}
}
Returns a specific Action object for a Storage Box.
GET /storage_boxes/{id}/actions/{action_id}
ID of the Storage Box.
ID of the Action.
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID/actions/$ACTION_ID"
Content-Type: application/json
Status: 200
{
"action": {
"id": 42,
"command": "start_resource",
"status": "running",
"started": "2016-01-30T23:55:00+00:00",
"finished": "2016-01-30T23:55:00+00:00",
"progress": 100,
"resources": [
{
"id": 42,
"type": "server"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Changes the protection configuration of the Storage Box.
POST /storage_boxes/{id}/actions/change_protection
ID of the Storage Box.
Prevent the Resource from being deleted.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"delete":false}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/actions/change_protection"
{
"delete": false
}
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "change_protection",
"status": "success",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
}
],
"error": null
}
}
Requests a Storage Box to be upgraded or downgraded to another Storage Box Type.
Please note that it is not possible to downgrade to a Storage Box Type that offers less disk space than you are currently using.
POST /storage_boxes/{id}/actions/change_type
ID of the Storage Box.
The ID or the name of the Storage Box Type.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"storage_box_type":"BX21"}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/actions/change_type"
{
"storage_box_type": "BX21"
}
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "change_type",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Reset the password of the given Storage Box.
POST /storage_boxes/{id}/actions/reset_password
ID of the Storage Box.
New password.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"password":"string"}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/actions/reset_password"
{
"password": "string"
}
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "reset_password",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Update access settings of the primary Storage Box account.
This endpoints supports partial updates. Omitted optional parameters do not result in any changes to the respective properties.
POST /storage_boxes/{id}/actions/update_access_settings
ID of the Storage Box.
Whether the Samba subsystem should be enabled.
Whether the SSH subsystem should be enabled.
Whether the WebDAV subsystem should be enabled.
Whether the ZFS Snapshot folder should be visible.
Whether the Storage Box should be accessible from outside the Hetzner network.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"samba_enabled":false,"ssh_enabled":true,"webdav_enabled":false,"zfs_enabled":false,"reachable_externally":false}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/actions/update_access_settings"
{
"samba_enabled": false,
"ssh_enabled": true,
"webdav_enabled": false,
"zfs_enabled": false,
"reachable_externally": false
}
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "update_access_settings",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Rolls back the Storage Box to the given Snapshot.
This action will remove all newer Snapshots and irrevocably delete all data that was since written to the Storage Box.
POST /storage_boxes/{id}/actions/rollback_snapshot
ID of the Storage Box.
ID of the Storage Box Snapshot.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"snapshot_id":42}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/actions/rollback_snapshot"
{
"snapshot_id": 42
}
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "rollback_snapshot",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
},
{
"id": 42,
"type": "snapshot"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Disables the active Snapshot Plan.
This action doesn't result in the deletion of the Snapshots created by the Snapshot Plan. They must be removed manually.
POST /storage_boxes/{id}/actions/disable_snapshot_plan
ID of the Storage Box.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID/actions/disable_snapshot_plan"
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "disable_snapshot_plan",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Enables a Snapshot Plan for a given StorageBox. Once enabled, a Snapshot Plan will create Snapshots at predefined intervals. There can only ever be one Snapshot Plan. The existing Snapshot Plan will be deleted before a new one is set up.
Automatic Snapshots are retained until explicitly deleted by the user or the maximum snapshot count for the plan ("max_snapshots") is exceeded.
You can choose the specific time (UTC timezone), day of the week, and day of the month. The time-related options are cron like. Some typical use cases include:
Interval | Request body |
---|---|
Every day at 3 o'clock | {"max_snapshots":10,"minute":0,"hour":3} |
Every Friday at 3 o'clock | {"max_snapshots":10,"minute":0,"hour":3,"day_of_week": 5} |
On the first of every month at half past 6 | {"max_snapshots":10,"minute":30,"hour":6,"day_of_month": 1} |
POST /storage_boxes/{id}/actions/enable_snapshot_plan
ID of the Storage Box.
Maximum amount of Snapshots that should be created by this Snapshot Plan. Older Snapshots will be deleted.
Minute the Snapshot Plan should be executed on (UTC). Null means every minute.
Hour the Snapshot Plan should be executed on (UTC). Null means every hour.
Day of the week the Snapshot Plan should be executed on. Starts at 1 for Monday til 7 for Sunday. Null means every day.
Day of the month the Snapshot Plan should be executed on. Null means every day.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"max_snapshots":10,"minute":30,"hour":3,"day_of_week":null,"day_of_month":null}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/actions/enable_snapshot_plan"
{
"max_snapshots": 10,
"minute": 30,
"hour": 3,
"day_of_week": null,
"day_of_month": null
}
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "enable_snapshot_plan",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
You can create additional users for a Storage Box. FTP, FTPS, SFTP, SCP, SMB/CIFS, HTTPS, and WebDAV are all available as protocols for these users. Additional Subaccounts can only access a sub-directory of the main user, and they use the storage space of the main user. The main user will have complete access to the directories of all Subaccounts.
To access a Subaccount, you use the Subaccount's username and the domain of the Subaccount (e.g uXXXXX-subX.your-storagebox.de
) instead of the main account's username.
It is possible to grant a Subaccount only read-access to a directory which prevents it from uploading, deleting, and modifying files.
Please note that each Subaccount requires its own authorized_keys
file. You can find more detailed instructions here.
You can only delete a Subaccount's home directory if you have already deleted the Subaccount itself.
Get a list of all available Subaccounts.
GET /storage_boxes/{id}/subaccounts
ID of the Storage Box.
Filter resources by labels. The response will only contain resources matching the label selector. For more information, see "Label Selector".
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID/subaccounts"
Content-Type: application/json
Status: 200
{
"subaccounts": [
{
"id": 42,
"username": "u1337-sub1",
"server": "u1337-sub1.your-storagebox.de",
"home_directory": "my_backups/host01.my.company",
"access_settings": {
"samba_enabled": false,
"ssh_enabled": true,
"webdav_enabled": false,
"reachable_externally": true,
"readonly": false
},
"description": "host01 backup",
"created": "2025-02-22:00:02.000Z",
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": null
},
"storage_box": 42
}
]
}
Creates a new Subaccount with a separate home directory.
POST /storage_boxes/{id}/subaccounts
ID of the Storage Box.
New password.
Home directory of the Subaccount. Will be created if it doesn't exist yet.
A description to remind you of the purpose of this Subaccount.
The Subaccounts' labels.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"password":"string","home_directory":"my-backup/server01","access_settings":{"samba_enabled":false,"ssh_enabled":true,"webdav_enabled":false,"readonly":false,"reachable_externally":false},"description":"my-backup-server01","labels":{"environment":"prod","example.com/my":"label","just-a-key":""}}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/subaccounts"
{
"password": "string",
"home_directory": "my-backup/server01",
"access_settings": {
"samba_enabled": false,
"ssh_enabled": true,
"webdav_enabled": false,
"readonly": false,
"reachable_externally": false
},
"description": "my-backup-server01",
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
}
}
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "create_subaccount",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
},
{
"id": 42,
"type": "storage_box_subaccount"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Returns a specific Subaccount object.
GET /storage_boxes/{id}/subaccounts/{subaccount_id}
ID of the Storage Box.
ID of the Storage Box Subaccount.
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID/subaccounts/$SUBACCOUNT_ID"
Content-Type: application/json
Status: 200
{
"subaccount": {
"id": 42,
"username": "u1337-sub1",
"home_directory": "my_backups/host01.my.company",
"server": "u1337-sub1.your-storagebox.de",
"access_settings": {
"reachable_externally": false,
"readonly": false,
"samba_enabled": false,
"ssh_enabled": false,
"webdav_enabled": false
},
"description": "host01 backup",
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
},
"created": "2016-01-30T23:55:00+00:00",
"storage_box": 42
}
}
Updates the description and the labels of a Subaccount.
PUT /storage_boxes/{id}/subaccounts/{subaccount_id}
ID of the Storage Box.
ID of the Storage Box Subaccount.
The Subaccounts' labels.
A description to remind you of the purpose of this Subaccount.
curl \
-X PUT \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"labels":{"environment":"prod","example.com/my":"label","just-a-key":""},"description":"my-backup-server01"}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/subaccounts/$SUBACCOUNT_ID"
{
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
},
"description": "my-backup-server01"
}
Content-Type: application/json
Status: 200
{
"subaccount": {
"id": 42,
"username": "u1337-sub1",
"home_directory": "my_backups/host01.my.company",
"server": "u1337-sub1.your-storagebox.de",
"access_settings": {
"reachable_externally": false,
"readonly": false,
"samba_enabled": false,
"ssh_enabled": false,
"webdav_enabled": false
},
"description": "host01 backup",
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
},
"created": "2016-01-30T23:55:00+00:00",
"storage_box": 42
}
}
Deletes an existing subaccount.
DELETE /storage_boxes/{id}/subaccounts/{subaccount_id}
ID of the Storage Box.
ID of the Storage Box Subaccount.
curl \
-X DELETE \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID/subaccounts/$SUBACCOUNT_ID"
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "delete_subaccount",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
},
{
"id": 42,
"type": "storage_box_subaccount"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Reset the password of the given Subaccount.
POST /storage_boxes/{id}/subaccounts/{subaccount_id}/actions/reset_subaccount_password
ID of the Storage Box.
ID of the Storage Box Subaccount.
New password.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"password":"string"}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/subaccounts/$SUBACCOUNT_ID/actions/reset_subaccount_password"
{
"password": "string"
}
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "reset_subaccount_password",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
},
{
"id": 42,
"type": "storage_box_subaccount"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Updates the access settings of a Subaccount.
This endpoints supports partial updates. Omitted optional parameters do not result in any changes to the respective properties.
POST /storage_boxes/{id}/subaccounts/{subaccount_id}/actions/update_access_settings
ID of the Storage Box.
ID of the Storage Box Subaccount.
Home directory of the Subaccount. Will be created if it doesn't exist yet.
Whether the Samba subsystem should be enabled.
Whether the SSH subsystem should be enabled.
Whether the WebDAV subsystem should be enabled.
Whether the Subaccount should be read-only.
Whether the Subaccount should be accessible from outside the Hetzner network.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"home_directory":"my-backup/server01","samba_enabled":false,"ssh_enabled":true,"webdav_enabled":false,"readonly":false,"reachable_externally":false}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/subaccounts/$SUBACCOUNT_ID/actions/update_access_settings"
{
"home_directory": "my-backup/server01",
"samba_enabled": false,
"ssh_enabled": true,
"webdav_enabled": false,
"readonly": false,
"reachable_externally": false
}
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "update_access_settings",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
},
{
"id": 42,
"type": "storage_box_subaccount"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Get all Snapshots created both manually and through the Snapshot Plan.
GET /storage_boxes/{id}/snapshots
ID of the Storage Box.
Filter resources by their name. The response will only contain the resources matching exactly the specified name.
Filter resources by labels. The response will only contain resources matching the label selector. For more information, see "Label Selector".
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID/snapshots"
Content-Type: application/json
Status: 200
{
"snapshots": [
{
"id": 1,
"stats": {
"size": 2097152,
"size_filesystem": 1048576
},
"is_automatic": false,
"name": "2025-02-12T11-35-19",
"description": "my-description",
"created": "2025-02-12T11:35:19.000Z",
"storage_box": 42,
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": null
}
},
{
"id": 2,
"stats": {
"size": 2097152,
"size_filesystem": 1048576
},
"is_automatic": true,
"name": "snapshot-daily--2025-02-12T22-00-02",
"description": "",
"created": "2025-02-22:00:02.000Z",
"storage_box": 42,
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": null
}
}
]
}
Creates a new Snapshot.
POST /storage_boxes/{id}/snapshots
ID of the Storage Box.
Description of the Snapshot.
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"description":"snapshot-0001"}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/snapshots"
{
"description": "snapshot-0001"
}
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "create_snapshot",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
},
{
"id": 42,
"type": "storage_box_snapshot"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Returns a specific Snapshot object.
GET /storage_boxes/{id}/snapshots/{snapshot_id}
ID of the Storage Box.
ID of the Storage Box Snapshot.
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID/snapshots/$SNAPSHOT_ID"
Content-Type: application/json
Status: 200
{
"snapshot": {
"id": 42,
"name": "my-resource",
"description": "This describes my resource",
"stats": {
"size": 0,
"size_filesystem": 0
},
"is_automatic": false,
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
},
"created": "2016-01-30T23:55:00+00:00",
"storage_box": 42
}
}
Updates the name and labels of a Snapshot.
PUT /storage_boxes/{id}/snapshots/{snapshot_id}
ID of the Storage Box.
ID of the Storage Box Snapshot.
Description of the Snapshot.
The Snapshots' labels.
curl \
-X PUT \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"description":"snapshot-0001","labels":{"environment":"prod","example.com/my":"label","just-a-key":""}}' \
"https://api.hetzner.com/v1/storage_boxes/$ID/snapshots/$SNAPSHOT_ID"
{
"description": "snapshot-0001",
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
}
}
Content-Type: application/json
Status: 200
{
"snapshot": {
"id": 42,
"name": "my-resource",
"description": "This describes my resource",
"stats": {
"size": 0,
"size_filesystem": 0
},
"is_automatic": false,
"labels": {
"environment": "prod",
"example.com/my": "label",
"just-a-key": ""
},
"created": "2016-01-30T23:55:00+00:00",
"storage_box": 42
}
}
Delete the given Snapshot.
DELETE /storage_boxes/{id}/snapshots/{snapshot_id}
ID of the Storage Box.
ID of the Storage Box Snapshot.
curl \
-X DELETE \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_boxes/$ID/snapshots/$SNAPSHOT_ID"
Content-Type: application/json
Status: 201
{
"action": {
"id": 13,
"command": "delete_snapshot",
"status": "running",
"progress": 0,
"started": "2016-01-30T23:50:00+00:00",
"finished": null,
"resources": [
{
"id": 42,
"type": "storage_box"
},
{
"id": 42,
"type": "storage_box_snapshot"
}
],
"error": {
"code": "action_failed",
"message": "Action failed"
}
}
}
Storage Box types define storage products of different sizes. Each type has an hourly and a monthly cost. You will pay whichever cost is lower for your usage of this specific Storage Box. Costs may differ between Locations.
All prices are displayed in the currency of the project owner's account.
Gets all Storage Box type objects.
GET /storage_box_types
Filter resources by their name. The response will only contain the resources matching exactly the specified name.
25
Maximum number of entries returned per page. For more information, see "Pagination".
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_box_types"
Content-Type: application/json
Status: 200
{
"storage_box_types": [
{
"id": 42,
"name": "bx11",
"description": "BX11",
"snapshot_limit": 10,
"automatic_snapshot_limit": 10,
"subaccounts_limit": 200,
"size": 1073741824,
"prices": [
{
"location": "fsn1",
"price_hourly": {
"net": "1.0000",
"gross": "1.1900"
},
"price_monthly": {
"net": "1.0000",
"gross": "1.1900"
},
"setup_fee": {
"net": "1.0000",
"gross": "1.1900"
}
}
],
"deprecation": {
"unavailable_after": "2023-09-01T00:00:00+00:00",
"announced": "2023-06-01T00:00:00+00:00"
}
}
],
"meta": {
"pagination": {
"page": 3,
"per_page": 25,
"previous_page": 2,
"next_page": 4,
"last_page": 4,
"total_entries": 100
}
}
}
Gets a specific Storage Box type object.
GET /storage_box_types/{id}
ID of the Storage Box Type.
curl \
-H "Authorization: Bearer $API_TOKEN" \
"https://api.hetzner.com/v1/storage_box_types/$ID"
Content-Type: application/json
Status: 200
{
"storage_box_type": {
"id": 42,
"name": "bx11",
"description": "BX11",
"snapshot_limit": 10,
"automatic_snapshot_limit": 10,
"subaccounts_limit": 200,
"size": 1073741824,
"prices": [
{
"location": "fsn1",
"price_hourly": {
"net": "1.0000",
"gross": "1.1900"
},
"price_monthly": {
"net": "1.0000",
"gross": "1.1900"
},
"setup_fee": {
"net": "1.0000",
"gross": "1.1900"
}
}
],
"deprecation": {
"unavailable_after": "2023-09-01T00:00:00+00:00",
"announced": "2023-06-01T00:00:00+00:00"
}
}
}