UNPKG

openapi-directory

Version:

Building & bundling https://github.com/APIs-guru/openapi-directory for easy use from JS

1 lines 616 kB
{"openapi":"3.0.0","servers":[{"url":"https://api.hetzner.cloud/v1"}],"info":{"description":"This is the official API documentation for the Public Hetzner Cloud.\n\n## Introduction\n\nThe Hetzner Cloud 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.\n\nAs an alternative to working directly with our API you may also consider to use:\n* Our CLI program [hcloud](https://github.com/hetznercloud/cli)\n* Our [library for Go](https://github.com/hetznercloud/hcloud-go)\n* Our [library for Python](https://github.com/hetznercloud/hcloud-python)\n\nAlso you can find a [list of libraries, tools, and integrations on GitHub](https://github.com/hetznercloud/awesome-hcloud).\n\nIf you are developing integrations based on our API and your product is Open Source you may be eligible for a free one time €50 (excl. VAT) credit on your account. Please contact us via the the support page on your Cloud Console and let us know the following:\n* The type of integration you would like to develop\n* Link to the GitHub repo you will use for the Project\n* Link to some other Open Source work you have already done (if you have done so)\n\n## Getting Started\nTo get started using the API you first need an API token. Sign in into the [Hetzner Cloud Console](https://console.hetzner.cloud/) 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 `jEheVytlAoFl7F8MqUQ7jAo2hOXASztX`.\n\nYou’re now ready to do your first request against the API. To get a list of all Servers in your Project, issue the example request on the right side using [curl](https://curl.haxx.se/).\n\nMake sure to replace the token in the example command with the token you have just created. Since your Project probably does not contain any Servers yet, the example response will look like the response on the right side. We will almost always provide a resource root like `servers` inside the example response. A response can also contain a `meta` object with information like [Pagination](https://docs.hetzner.cloud/#overview-pagination).\n\n**Example Request**\n```bash\ncurl -H \"Authorization: Bearer jEheVytlAoFl7F8MqUQ7jAo2hOXASztX\" \\\n https://api.hetzner.cloud/v1/servers\n```\n\n**Example Response**\n```json\n{\n \"servers\": [],\n \"meta\": {\n \"pagination\": {\n \"page\": 1,\n \"per_page\": 25,\n \"previous_page\": null,\n \"next_page\": null,\n \"last_page\": 1,\n \"total_entries\": 0\n }\n }\n}\n```\n\n## Authentication\nAll requests to the Hetzner Cloud 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.\n\nTo create a new API token for your Project, switch into the [Hetzner Cloud Console](https://console.hetzner.cloud/) choose a Project, go to `Security` → `API Tokens`, and generate a new token.\n\n**Example Authorization header**\n```html\nAuthorization: Bearer LRK9DAWQ1ZAEFSrCNEEzLCUwhYX1U3g7wMg4dTlkkDC96fyDuyJ39nVbVjCKSDfj\n```\n\n## Errors\nErrors 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.\n\nThe error response contains the following keys:\n\n| Keys | Meaning |\n|-----------|-----------------------------------------------------------------------|\n| `code` | Short string indicating the type of error (machine-parsable) |\n| `message` | Textual description on what has gone wrong |\n| `details` | An object providing for details on the error (schema depends on code) |\n\n**Example response**\n```json\n{\n \"error\": {\n \"code\": \"invalid_input\",\n \"message\": \"invalid input in field 'broken_field': is too long\",\n \"details\": {\n \"fields\": [\n {\n \"name\": \"broken_field\",\n \"messages\": [\"is too long\"]\n }\n ]\n }\n }\n}\n```\n\n### Error Codes\n\n| Code | Description |\n|---------------------------|----------------------------------------------------------------------------------|\n| `forbidden` | Insufficient permissions for this request |\n| `invalid_input` | Error while parsing or processing the input |\n| `json_error` | Invalid JSON input in your request |\n| `locked` | The item you are trying to access is locked (there is already an Action running) |\n| `not_found` | Entity not found |\n| `rate_limit_exceeded` | Error when sending too many requests |\n| `resource_limit_exceeded` | Error when exceeding the maximum quantity of a resource for an account |\n| `resource_unavailable` | The requested resource is currently unavailable |\n| `service_error` | Error within a service |\n| `uniqueness_error` | One or more of the objects fields must be unique |\n| `protected` | The Action you are trying to start is protected for this resource |\n| `maintenance` | Cannot perform operation due to maintenance |\n| `conflict` | The resource has changed during the request, please retry |\n| `unsupported_error` | The corresponding resource does not support the Action |\n| `token_readonly` | The token is only allowed to perform GET requests |\n| `unavailable` | A service or product is currently not available |\n\n**invalid_input**\n```json\n{\n \"error\": {\n \"code\": \"invalid_input\",\n \"message\": \"invalid input in field 'broken_field': is too long\",\n \"details\": {\n \"fields\": [\n {\n \"name\": \"broken_field\",\n \"messages\": [\"is too long\"]\n }\n ]\n }\n }\n}\n```\n\n**uniqueness_error**\n```json\n{\n \"error\": {\n \"code\": \"uniqueness_error\",\n \"message\": \"SSH key with the same fingerprint already exists\",\n \"details\": {\n \"fields\": [\n {\n \"name\": \"public_key\"\n }\n ]\n }\n }\n}\n```\n\n**resource_limit_exceeded**\n```json\n{\n \"error\": {\n \"code\": \"resource_limit_exceeded\",\n \"message\": \"project limit exceeded\",\n \"details\": {\n \"limits\": [\n {\n \"name\": \"project_limit\"\n }\n ]\n }\n }\n}\n```\n\n## Labels\nLabels are `key/value` pairs that can be attached to all resources.\n\nValid 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 (`/`).\n\nValid 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.\n\nThe `hetzner.cloud/` prefix is reserved and cannot be used.\n\n**Example Labels**\n```json\n{\n \"labels\": {\n \"environment\":\"development\",\n \"service\":\"backend\",\n \"example.com/my\":\"label\",\n \"just-a-key\":\"\"\n }\n}\n```\n\n## Label Selector\nFor resources with labels, you can filter resources by their labels using the label selector query language.\n\n| Expression | Meaning |\n|----------------------|---------------------------------------------------------------------|\n| `k==v` / `k=v` | Value of key `k` does equal value `v` |\n| `k!=v` | Value of key `k` does not equal value `v` |\n| `k` | Key `k` is present |\n| `!k` | Key `k` is not present |\n| `k in (v1,v2,v3)` | Value of key `k` is `v1`, `v2`, or `v3` |\n| `k notin (v1,v2,v3)` | Value of key `k` is neither `v1`, nor `v2`, nor `v3` |\n| `k1==v,!k2` | Value of key `k1` is `v` and key `k2` is not present |\n\n### Examples\n* Returns all resources that have a `env=production` label and that don't have a `type=database` label:\n\n `env=production,type!=database`\n* Returns all resources that have a `env=testing` or `env=staging` label:\n\n `env in (testing,staging)`\n* Returns all resources that don't have a `type` label:\n\n `!type`\n\n## Pagination\nResponses which return multiple items support pagination. If they do support pagination, it can be controlled with following query string parameters:\n\n* A `page` parameter specifies the page to fetch. The number of the first page is 1.\n* A `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.\n\nResponses contain a `Link` header with pagination information.\n\nAdditionally, 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:\n\n**Example Pagination**\n```json\n{\n \"servers\": [...],\n \"meta\": {\n \"pagination\": {\n \"page\": 2,\n \"per_page\": 25,\n \"previous_page\": 1,\n \"next_page\": 3,\n \"last_page\": 4,\n \"total_entries\": 100\n }\n }\n}\n```\n\nThe 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.\n\n**Example Pagination Link header**\n```bash\nLink: <https://api.hetzner.cloud/v1/actions?page=2&per_page=5>; rel=\"prev\",\n <https://api.hetzner.cloud/v1/actions?page=4&per_page=5>; rel=\"next\",\n <https://api.hetzner.cloud/v1/actions?page=6&per_page=5>; rel=\"last\"\n```\n\nLine breaks have been added for display purposes only and responses may only contain some of the above `rel` values.\n\n## Rate Limiting\nAll 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 serveral headers which provide information about your current rate limit status.\n\n* The `RateLimit-Limit` header contains the total number of requests you can perform per hour.\n* The `RateLimit-Remaining` header contains the number of requests remaining in the current rate limit time frame.\n* The `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.\n\nThe 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.\n\n## Server Metadata\nYour Server can discover metadata about itself by doing a HTTP request to specific URLs. The following data is available:\n\n| Data | Format | Contents |\n|-------------------|--------|--------------------------------------------------------------|\n| hostname | text | Name of the Server as set in the api |\n| instance-id | number | ID of the server |\n| public-ipv4 | text | Primary public IPv4 address |\n| private-networks | yaml | Details about the private networks the Server is attached to |\n| availability-zone | text | Name of the availability zone that Server runs in |\n| region | text | Network zone, e.g. eu-central |\n\n**Example: Summary**\n```bash\n$ curl http://169.254.169.254/hetzner/v1/metadata\n```\n\n```yaml\navailability-zone: hel1-dc2\nhostname: my-server\ninstance-id: 42\npublic-ipv4: 1.2.3.4\nregion: eu-central\n```\n\n**Example: Hostname**\n```bash\n$ curl http://169.254.169.254/hetzner/v1/metadata/hostname\nmy-server\n```\n\n**Example: Instance ID**\n```bash\n$ curl http://169.254.169.254/hetzner/v1/metadata/instance-id\n42\n```\n\n**Example: Public IPv4**\n```bash\n$ curl http://169.254.169.254/hetzner/v1/metadata/public-ipv4\n1.2.3.4\n```\n\n**Example: Private Networks**\n```bash\n$ curl http://169.254.169.254/hetzner/v1/metadata/private-networks\n```\n\n```json\n- ip: 10.0.0.2\n alias_ips: [10.0.0.3, 10.0.0.4]\n interface_num: 1\n mac_address: 86:00:00:2a:7d:e0\n network_id: 1234\n network_name: nw-test1\n network: 10.0.0.0/8\n subnet: 10.0.0.0/24\n gateway: 10.0.0.1\n- ip: 192.168.0.2\n alias_ips: []\n interface_num: 2\n mac_address: 86:00:00:2a:7d:e1\n network_id: 4321\n network_name: nw-test2\n network: 192.168.0.0/16\n subnet: 192.168.0.0/24\n gateway: 192.168.0.1\n```\n\n**Example: Availability Zone**\n```bash\n$ curl http://169.254.169.254/hetzner/v1/metadata/availability-zone\nhel1-dc2\n```\n\n**Example: Region**\n```bash\n$ curl http://169.254.169.254/hetzner/v1/metadata/region\neu-central\n```\n\n## Sorting\nSome 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.\n\n**Example: Sorting**\n```bash\nhttps://api.hetzner.cloud/v1/actions?sort=status\nhttps://api.hetzner.cloud/v1/actions?sort=status:asc\nhttps://api.hetzner.cloud/v1/actions?sort=status:desc\nhttps://api.hetzner.cloud/v1/actions?sort=status:asc&sort=command:desc\n```\n","title":"Hetzner Cloud API","version":"1.0.0","x-apisguru-categories":["hosting"],"x-logo":{"url":"https://www.hetzner.com/themes/hetzner/images/favicons/apple-touch-icon.png"},"x-origin":[{"format":"openapi","url":"https://docs.hetzner.cloud/spec.json","version":"3.0"}],"x-providerName":"hetzner.cloud"},"tags":[{"description":"Actions show the results and progress of asynchronous requests to the API.","name":"Actions"},{"description":"TLS/SSL Certificates prove the identity of a Server and are used to encrypt client traffic.","name":"Certificates"},{"name":"Certificate Actions"},{"description":"Each Datacenter represents a *virtual* Datacenter which is made up of possible many physical Datacenters where Servers are hosted.\n\nDatacenter names are composed from their Location and virtual Datacenter number, for example `fsn1-dc14` means virtual Datacenter `14` in Location `fsn1`.\n\nRight now there is only one Datacenter for each Location. The Datacenter numbers for `fsn`, `nbg` and `hel` are arbitrarily set to `14`, `3` and `2` for historic reasons and do not represent real physical Hetzner datacenters.\n","name":"Datacenters"},{"description":"Firewalls can limit the network access to or from your resources.\n\n* When applying a firewall with no `in` rule all inbound traffic will be dropped. The default for `in` is `DROP`.\n* When applying a firewall with no `out` rule all outbound traffic will be accepted. The default for `out` is `ACCEPT`.\n","name":"Firewalls"},{"name":"Firewall Actions"},{"description":"Floating IPs help you to create highly available setups. You can assign a Floating IP to any Server. The Server can then use this IP. You can reassign it to a different Server at any time, or you can choose to unassign the IP from Servers all together.\n\nFloating IPs can be used globally. This means you can assign a Floating IP to a Server in one Location and later reassign it to a Server in a different Location. For optimal routing and latency Floating IPs should be used in the Location they were created in.\n\nFor Floating IPs to work with your Server, you must configure them inside your operation system.\n\nFloating IPs of type `ipv4` use a single IPv4 address as their `ip` property. Floating IPs of type `ipv6` use a /64 network such as `fc00::/64` as their `ip` property. Any IP address within that network can be used on your host.\n\nFloating IPs are billed on a monthly basis.\n","name":"Floating IPs"},{"name":"Floating IP Actions"},{"description":"Images are blueprints for your VM disks. They can be of different types:\n\n### System Images\nDistribution Images maintained by us, e.g. “Ubuntu 20.04”\n\n### Snapshot Images\nMaintained by you, for example “Ubuntu 20.04 with my own settings”. These are billed per GB per month.\n\n### Backup Images\nDaily Backups of your Server. Will automatically be created for Servers which have backups enabled (`POST /servers/{id}/actions/enable_backup`)\n\nBound to exactly one Server. If you delete the Server, you also delete all backups bound to it. You may convert backup Images to snapshot Images to keep them.\n\nThese are billed at 20% of your instance price for 7 backup slots.\n\n### App Images\nPrebuild images with specific software configurations, e.g. “Wordpress”. All app images are created by us.\n","name":"Images"},{"name":"Image Actions"},{"description":"ISOs are read-only Images of DVDs. While we recommend using our Image functionality to install your Servers we also provide some stock ISOs so you can install more exotic operating systems by yourself.\n\nOn request our support uploads a private ISO just for you. These are marked with type `private` and only visible in your Project.\n\nTo attach an ISO to your Server use `POST /servers/{id}/actions/attach_iso`.\n","name":"ISOs"},{"name":"Load Balancers"},{"name":"Load Balancer Actions"},{"description":"Load Balancer types define kinds of Load Balancers offered. Each type has an hourly and a monthly cost. You will pay whichever amount is lower for your usage of this specific Load Balancer. Costs may differ between Locations.\n\nCurrency for all amounts is €. All prices exclude VAT.\n","name":"Load Balancer Types"},{"description":"Datacenters are organized by Locations. Datacenters in the same Location are connected with very low latency links.","name":"Locations"},{"description":"Primary IPs help you to create more flexible networking setups. You can assign at most one Primary IP of type `ipv4` and one of type `ipv6` per Server. This Server then uses these IPs.\n\nYou can only unassign a Primary IP from a Server when it's powered off. This Primary IP can then be assigned to a different powered off Server, or you can keep it around for later use.\n\nPrimary IPs are bound to a specific Datacenter. You can not assign a Primary IP from one Datacenter to a Server in a different Datacenter. If you need this capability use Floating IPs instead.\n\nIf your Server's operating system supports cloud-init there is no further configuration needed to make Primary IPs work.\n\nPrimary IPs of type `ipv4` use a single IPv4 address as their `ip` property. Primary IPs of type `ipv6` use a /64 network such as `fc00::/64` as their `ip` property. Any IP address within that network can be used on your host.\n\nPrimary IPs are billed on an hourly basis.\n","name":"Primary IPs"},{"name":"Primary IP Actions"},{"description":"Networks is a private networks feature. These Networks are optional and they coexist with the public network that every Server has by default.\n\nThey allow Servers to talk to each other over a dedicated network interface using private IP addresses not available publicly.\n\nThe IP addresses are allocated and managed via the API, they must conform to [RFC1918](https://tools.ietf.org/html/rfc1918#section-3) standard. IPs and network interfaces defined under Networks do not provide public internet connectivity, you will need to use the already existing public network interface for that.\n\nEach network has a user selected `ip_range` which defines all available IP addresses which can be used for Subnets within the Network.\n\nTo assign individual IPs to Servers you will need to create Network Subnets, described below.\n\nCurrently Networks support IPv4 only.\n\n### Subnets\nSubnets divide the `ip_range` from the parent Network object into multiple Subnetworks that you can use for different specific purposes.\n\nFor each subnet you need to specify its own `ip_range` which must be contained within the parent Network’s `ip_range`. Additionally each subnet must belong to one of the available Network Zones described below. Subnets can not have overlapping IP ranges.\n\nCurrently there are three types of subnet:\n* type `cloud` is used to connect cloud Resources into your Network.\n* type `server` was used to connect only cloud Servers into your Network. This type is deprecated and is replaced by type cloud.\n* type `vswitch` allows you to connect [Dedicated Server vSwitch](https://docs.hetzner.com/robot/dedicated-server/network/vswitch) - and all Dedicated Servers attached to it - into your Network\n\nSubnets of type `vswitch` must set a `vswitch_id` which is the ID of the existing vSwitch in Hetzner Robot that should be coupled.\n\n### Network Zones\nNetwork Zones are groups of Locations which have special high-speed network connections between them. The [Location object](https://docs.hetzner.cloud/#locations-get-a-location) contains the `network_zone` property each Location belongs to. Currently these network zones exist:\n\n|Network Zone|Contains Locations|\n|------------|------------------|\n|eu-central | nbg1, fsn1, hel1 |\n|us-east | ash |\n\n### IP address management\nWhen a cloud Server is attached to a network without the user specifying an IP it automatically gets an IP address assigned from a subnet of type `server` in the same network zone. If you specify the optional `ip` parameter when attaching then we will try to assign that IP. Keep in mind that the Server’s location must be covered by the Subnet’s Network Zone if you specify an IP, or that at least one Subnet with the zone covering Server’s location must exist.\n\nA cloud Server can also have more than one IP address in a Network by specifying aliases. For details see the [attach to network action](https://docs.hetzner.cloud/#server-actions-attach-a-server-to-a-network).\n\nThe following IP addresses are reserved in networks and can not be used:\n * the first IP of the network `ip_range` as it will be used as a default gateway for the private Network interface.\n * `172.31.1.1` as it is being used as default gateway for our public Network interfaces.\n\n### Coupling Dedicated Servers\n\nBy using subnets of type `vswitch` you can couple the Cloud Networks with an existing [Dedicated Server vSwitch](https://docs.hetzner.com/robot/dedicated-server/network/vswitch) and enable dedicated and cloud servers to\ntalk to each other over the Network.\nIn order for this to work the dedicated servers may only use IPs from the subnet and must have a special network configuration. Please refer to [FAQ](https://docs.hetzner.com/cloud/networks/connect-dedi-vswitch). vSwitch Layer 2 features are not supported.\n\n### Routes\nNetworks also support the notion of routes which are automatically applied to private traffic. A route makes sure that all packets for a given `destination` IP prefix will be sent to the address specified in its `gateway`.\n","name":"Networks"},{"name":"Network Actions"},{"description":"Placement groups are used to influence the location of interdependent virtual servers in our data centers. The distribution of the different instances within a group is based on a pattern specified in the type. By enforcing certain rules on the placement of instances within our infrastructure, availability can be influenced in a way that fits your needs best.\n\nIn `spread` placement groups, all virtual servers will run on different physical servers. This decreases the probability that some instances might fail together.\n","name":"Placement Groups"},{"description":"Returns prices for resources.","name":"Pricing"},{"description":"Servers are virtual machines that can be provisioned.","name":"Servers"},{"name":"Server Actions"},{"description":"Server types define kinds of Servers offered. Each type has an hourly and a monthly cost. You will pay whichever cost is lower for your usage of this specific Server. Costs may differ between Locations.\n\nCurrency for all amounts is €. All prices exclude VAT.\n","name":"Server Types"},{"description":"SSH keys are public keys you provide to the cloud system. They can be injected into Servers at creation time. We highly recommend that you use keys instead of passwords to manage your Servers.","name":"SSH Keys"},{"description":"A Volume is a highly-available, scalable, and SSD-based block storage for Servers.\n\nPricing for Volumes depends on the Volume size and Location, not the actual used storage.\n\nPlease see [Hetzner Docs](https://docs.hetzner.com/cloud/#Volumes) for more details about Volumes.\n","name":"Volumes"},{"name":"Volume Actions"}],"paths":{"/actions":{"get":{"description":"Returns all Action objects. You can `sort` the results by using the sort URI parameter, and filter them with the `status` parameter.","parameters":[{"description":"Can be used multiple times, the response will contain only Actions with specified IDs","in":"query","name":"id","required":false,"schema":{"type":"integer"}},{"description":"Can be used multiple times.","in":"query","name":"sort","required":false,"schema":{"enum":["id","id:asc","id:desc","command","command:asc","command:desc","status","status:asc","status:desc","progress","progress:asc","progress:desc","started","started:asc","started:desc","finished","finished:asc","finished:desc"],"title":"ParameterSort","type":"string"}},{"description":"Can be used multiple times, the response will contain only Actions with specified statuses","in":"query","name":"status","required":false,"schema":{"enum":["running","success","error"],"title":"ParameterStatus","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"actions":{"items":{"properties":{"command":{"description":"Command executed in the Action","example":"start_server","type":"string"},"error":{"description":"Error message for the Action if error occurred, otherwise null","nullable":true,"properties":{"code":{"description":"Fixed machine readable code","example":"action_failed","type":"string"},"message":{"description":"Humanized error message","example":"Action failed","type":"string"}},"required":["code","message"],"type":"object"},"finished":{"description":"Point in time when the Action was finished (in ISO-8601 format). Only set if the Action is finished otherwise null.","example":"2025-04-15T13:52:37.536Z","nullable":true,"type":"string"},"id":{"description":"ID of the Resource","example":42,"type":"integer"},"progress":{"description":"Progress of Action in percent","example":100,"type":"number"},"resources":{"description":"Resources the Action relates to","items":{"properties":{"id":{"description":"ID of the Resource","example":42,"type":"integer"},"type":{"description":"Type of resource referenced","example":"server","type":"string"}},"required":["id","type"],"type":"object"},"type":"array"},"started":{"description":"Point in time when the Action was started (in ISO-8601 format)","example":"2025-04-15T13:52:37.536Z","type":"string"},"status":{"description":"Status of the Action","enum":["success","running","error"],"type":"string"}},"required":["id","command","status","progress","started","finished","resources","error"],"title":"Action","type":"object"},"type":"array"},"meta":{"properties":{"pagination":{"properties":{"last_page":{"description":"ID of the last page available. Can be null if the current page is the last one.","example":4,"nullable":true,"type":"number"},"next_page":{"description":"ID of the next page. Can be null if the current page is the last one.","example":4,"nullable":true,"type":"number"},"page":{"description":"Current page number","example":3,"type":"number"},"per_page":{"description":"Maximum number of items shown per page in the response","example":25,"type":"number"},"previous_page":{"description":"ID of the previous page. Can be null if the current page is the first one.","example":2,"nullable":true,"type":"number"},"total_entries":{"description":"The total number of entries that exist in the database for this query. Nullable if unknown.","example":100,"nullable":true,"type":"number"}},"required":["page","per_page","previous_page","next_page","last_page","total_entries"],"type":"object"}},"required":["pagination"],"type":"object"}},"required":["actions"],"title":"ActionsResponse","type":"object"}}},"description":"The `actions` key contains a list of Actions"}},"summary":"Get all Actions","tags":["Actions"]}},"/actions/{id}":{"get":{"description":"Returns a specific Action object.","parameters":[{"description":"ID of the Resource","in":"path","name":"id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"action":{"properties":{"command":{"description":"Command executed in the Action","example":"start_server","type":"string"},"error":{"description":"Error message for the Action if error occurred, otherwise null","nullable":true,"properties":{"code":{"description":"Fixed machine readable code","example":"action_failed","type":"string"},"message":{"description":"Humanized error message","example":"Action failed","type":"string"}},"required":["code","message"],"type":"object"},"finished":{"description":"Point in time when the Action was finished (in ISO-8601 format). Only set if the Action is finished otherwise null.","example":"2025-04-15T13:52:37.536Z","nullable":true,"type":"string"},"id":{"description":"ID of the Resource","example":42,"type":"integer"},"progress":{"description":"Progress of Action in percent","example":100,"type":"number"},"resources":{"description":"Resources the Action relates to","items":{"properties":{"id":{"description":"ID of the Resource","example":42,"type":"integer"},"type":{"description":"Type of resource referenced","example":"server","type":"string"}},"required":["id","type"],"type":"object"},"type":"array"},"started":{"description":"Point in time when the Action was started (in ISO-8601 format)","example":"2025-04-15T13:52:37.536Z","type":"string"},"status":{"description":"Status of the Action","enum":["success","running","error"],"type":"string"}},"required":["id","command","status","progress","started","finished","resources","error"],"title":"Action","type":"object"}},"required":["action"],"title":"ActionResponse","type":"object"}}},"description":"The `action` key in the reply has this structure"}},"summary":"Get an Action","tags":["Actions"]}},"/certificates":{"get":{"description":"Returns all Certificate objects.","parameters":[{"description":"Can be used multiple times.","in":"query","name":"sort","required":false,"schema":{"enum":["id","id:asc","id:desc","name","name:asc","name:desc","created","created:asc","created:desc"],"type":"string"}},{"description":"Can be used to filter resources by their name. The response will only contain the resources matching the specified name","in":"query","name":"name","required":false,"schema":{"type":"string"}},{"description":"Can be used to filter resources by labels. The response will only contain resources matching the label selector.","in":"query","name":"label_selector","required":false,"schema":{"type":"string"}},{"description":"Can be used multiple times. The response will only contain Certificates matching the type.","in":"query","name":"type","required":false,"schema":{"enum":["uploaded","managed"],"title":"ParameterType","type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"certificates":[{"certificate":"-----BEGIN CERTIFICATE-----\n...","created":"2025-04-15T13:52:37.536Z","domain_names":["example.com","webmail.example.com","www.example.com"],"fingerprint":"03:c7:55:9b:2a:d1:04:17:09:f6:d0:7f:18:34:63:d4:3e:5f","id":897,"labels":{"env":"dev"},"name":"my website cert","not_valid_after":"2025-04-15T13:52:37.536Z","not_valid_before":"2025-04-15T13:52:37.536Z","status":null,"type":"uploaded","used_by":[{"id":4711,"type":"load_balancer"}]}]},"schema":{"properties":{"certificates":{"items":{"properties":{"certificate":{"description":"Certificate and chain in PEM format, in order so that each record directly certifies the one preceding","example":"-----BEGIN CERTIFICATE-----\n...","nullable":true,"type":"string"},"created":{"description":"Point in time when the Resource was created (in ISO-8601 format)","example":"2025-04-15T13:52:37.536Z","type":"string"},"domain_names":{"description":"Domains and subdomains covered by the Certificate","example":["example.com","webmail.example.com","www.example.com"],"items":{"type":"string"},"type":"array"},"fingerprint":{"description":"SHA256 fingerprint of the Certificate","example":"03:c7:55:9b:2a:d1:04:17:09:f6:d0:7f:18:34:63:d4:3e:5f","nullable":true,"type":"string"},"id":{"description":"ID of the Resource","example":42,"type":"integer"},"labels":{"additionalProperties":{"type":"string"},"description":"User-defined labels (key-value pairs)","type":"object"},"name":{"description":"Name of the Resource. Must be unique per Project.","example":"my-resource","type":"string"},"not_valid_after":{"description":"Point in time when the Certificate stops being valid (in ISO-8601 format)","example":"2025-04-15T13:52:37.536Z","nullable":true,"type":"string"},"not_valid_before":{"description":"Point in time when the Certificate becomes valid (in ISO-8601 format)","example":"2025-04-15T13:52:37.536Z","nullable":true,"type":"string"},"status":{"description":"Current status of a type `managed` Certificate, always *null* for type `uploaded` Certificates","nullable":true,"properties":{"error":{"description":"If issuance or renewal reports `failed`, this property contains information about what happened","example":null,"nullable":true,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"type":"object"},"issuance":{"description":"Status of the issuance process of the Certificate","enum":["pending","completed","failed"],"example":"valid","type":"string"},"renewal":{"description":"Status of the renewal process of the Certificate.","enum":["scheduled","pending","failed","unavailable"],"example":"scheduled","type":"string"}},"type":"object"},"type":{"description":"Type of the Certificate","enum":["uploaded","managed"],"example":"uploaded","type":"string"},"used_by":{"description":"Resources currently using the Certificate","items":{"properties":{"id":{"description":"ID of resource referenced","example":4711,"type":"integer"},"type":{"description":"Type of resource referenced","example":"load_balancer","type":"string"}},"required":["id","type"],"type":"object"},"type":"array"}},"required":["id","name","labels","certificate","created","not_valid_before","not_valid_after","domain_names","fingerprint","used_by"],"title":"Certificate","type":"object"},"type":"array"},"meta":{"properties":{"pagination":{"properties":{"last_page":{"description":"ID of the last page available. Can be null if the current page is the last one.","example":4,"nullable":true,"type":"number"},"next_page":{"description":"ID of the next page. Can be null if the current page is the last one.","example":4,"nullable":true,"type":"number"},"page":{"description":"Current page number","example":3,"type":"number"},"per_page":{"description":"Maximum number of items shown per page in the response","example":25,"type":"number"},"previous_page":{"description":"ID of the previous page. Can be null if the current page is the first one.","example":2,"nullable":true,"type":"number"},"total_entries":{"description":"The total number of entries that exist in the database for this query. Nullable if unknown.","example":100,"nullable":true,"type":"number"}},"required":["page","per_page","previous_page","next_page","last_page","total_entries"],"type":"object"}},"required":["pagination"],"type":"object"}},"required":["certificates"],"title":"CertificatesResponse","type":"object"}}},"description":"The `certificates` key contains an array of Certificate objects"}},"summary":"Get all Certificates","tags":["Certificates"]},"post":{"description":"Creates a new Certificate.\n\nThe default type **uploaded** allows for uploading your existing `certificate` and `private_key` in PEM format. You have to monitor its expiration date and handle renewal yourself.\n\nIn contrast, type **managed** requests a new Certificate from *Let's Encrypt* for the specified `domain_names`. Only domains managed by *Hetzner DNS* are supported. We handle renewal and timely alert the project owner via email if problems occur.\n\nFor type `managed` Certificates the `action` key of the response contains the Action that allows for tracking the issuance process. For type `uploaded` Certificates the `action` is always null.\n","requestBody":{"content":{"application/json":{"examples":{"managed":{"summary":"Creating a type `managed` Certificate","value":{"domain_names":["example.com","webmail.example.com","www.example.com"],"name":"my website cert","type":"managed"}},"uploaded":{"summary":"Creating a type `uploaded` Certificate","value":{"certificate":"-----BEGIN CERTIFICATE-----\n...","name":"my website cert","private_key":"-----BEGIN PRIVATE KEY-----\n...","type":"uploaded"}}},"schema":{"properties":{"certificate":{"description":"Certificate and chain in PEM format, in order so that each record directly certifies the one preceding. Required for type `uploaded` Certificates.","example":"-----BEGIN CERTIFICATE-----\n...","type":"string"},"domain_names":{"description":"Domains and subdomains that should be contained in the Certificate issued by *Let's Encrypt*. Required for type `managed` Certificates.","example":null,"items":{"type":"string"},"type":"array"},"labels":{"description":"User-defined labels (key-value pairs)","type":"object"},"name":{"description":"Name of the Certificate","example":"my website cert","type":"string"},"private_key":{"description":"Certificate key in PEM format. Required for type `uploaded` Certificates.","example":"-----BEGIN PRIVATE KEY-----\n...","type":"string"},"type":{"description":"Choose between uploading a Certificate in PEM format or requesting a managed *Let's Encrypt* Certificate. If omitted defaults to `uploaded`.","enum":["uploaded","managed"],"example":"uploaded","type":"string"}},"required":["name"],"title":"CreateCertificateRequest","type":"object"}}}},"responses":{"201":{"content":{"application/json":{"examples":{"managed":{"summary":"Response when creating a type `managed` Certificate","value":{"action":{"command":"create_certificate","error":{"code":"action_failed","message":"Action failed"},"finished":null,"id":13,"progress":0,"resources":[{"id":879,"type":"certificate"}],"started":"2025-04-15T13:52:37.536Z","status":"running"},"certificate":{"certificate":null,"created":"2025-04-15T13:52:37.536Z","domain_names":["example.com","webmail.example.com","www.example.com"],"fingerprint":null,"id":897,"labels":{"env":"dev"},"name":"my website cert","not_valid_after":null,"not_valid_before":null,"status":{"error":null,"issuance":"pending","renewal":"unavailable"},"type":"managed","used_by":[{"id":4711,"type":"load_balancer"}]}}},"uploaded":{"summary":"Response when creating a type `uploaded` Certificate","value":{"action":null,"certificate":{"certificate":"-----BEGIN CERTIFICATE-----\n...","created":"2025-04-15T13:52:37.536Z","domain_names":["example.com","webmail.example.com","www.example.com"],"fingerprint":"03:c7:55:9b:2a:d1:04:17:09:f6:d0:7f:18:34:63:d4:3e:5f","id":897,"labels":{"env":"dev"},"name":"my website cert","not_valid_after":"2025-04-15T13:52:37.536Z","not_valid_before":"2025-04-15T13:52:37.536Z","status":null,"type":"uploaded","used_by":[{"id":4711,"type":"load_balancer"}]}}}},"schema":{"properties":{"action":{"nullable":true,"properties":{"command":{"description":"Command executed in the Action","example":"start_server","type":"string"},"error":{"description":"Error message for the Action if error occurred, otherwise null","nullable":true,"properties":{"code":{"description":"Fixed machine readable code","example":"action_failed","type":"string"},"message":{"description":"Humanized error message","example":"Action failed","type":"string"}},"required":["code","message"],"type":"object"},"finished":{"description":"Point in time when the Action was finished (in ISO-8601 format). Only set if the Action is finished otherwise null.","example":"2025-04-15T13:52:37.536Z","nullable":true,"type":"string"},"id":{"description":"ID of the Resource","example":42,"type":"integer"},"progress":{"description":"Progress of Action in percent","example":100,"type":"number"},"resources":{"description":"Resources the Action relates to","items":{"properties":{"id":{"description":"ID of the Resource","example":42,"type":"integer"},"type":{"description":"Type of resource referenced","example":"server","type":"string"}},"required":["id","type"],"type":"object"},"type":"array"},"started":{"description":"Point in time when the Action was started (in ISO-8601 format)","example":"2025-04-15T13:52:37.536Z","type":"string"},"status":{"description":"Status of the Action","enum":["success","running","error"],"type":"string"}},"required":["id","command","status","progress","started","finished","resources","error"],"title":"NullableAction","type":"object"},"certificate":{"properties":{"certificate":{"description":"Certificate and chain in PEM format, in order so that each record directly certifies the one preceding","example":"-----BEGIN CERTIFICATE-----\n...","nullable":true,"type":"string"},"created":{"description":"Point in time when the Resource was created (in ISO-8601 format)","example":"2025-04-15T13:52:37.536Z","type":"string"},"domain_names":{"description":"Domains and subdomains covered by the Certificate","example":["example.com","webmail.example.com","www.example.com"],"items":{"type":"string"},"type":"array"},"fingerprint":{"description":"SHA256 fingerprint of the Certificate","example":"03:c7:55:9b:2a:d1:04:17:09:f6:d0:7f:18:34:63:d4:3e:5f","nullable":true,"type":"string"},"id":{"description":"ID of the Resource","example":42,"type":"integer"},"labels":{"additionalProperties":{"type":"string"},"description":"User-defined labels (key-value pairs)","type":"object"},"name":{"description":"Name of the Resource. Must be unique per Project.","example":"my-resource","type":"string"},"not_valid_after":{"description":"Point in time when the Certificate stops being valid (in ISO-8601 format)","example":"2025-04-15T13:52:37.540Z","nullable":true,"type":"string"},"not_valid_before":{"description":"Point in time when the Certificate becomes valid (in ISO-8601 format)","example":"2025-04-15T13:52:37.540Z","nullable":true,"type":"string"},"status":{"description":"Current status of a type `managed` Certificate, always *null* for type `uploaded` Certificates","nullable":true,"properties":{"error":{"description":"If issuance or renewal reports `failed`, this property contains information about what happened","example":null,"nullable":true,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"type":"object"},"issuance":{"description":"Status of the issuance process of the Certificate","enum":["pending","completed","failed"],"example":"valid","type":"string"},"renewal":{"description":"Status of the renewal process of the Certificate.","enum":["scheduled","pending","failed","unavailable"],"example":"scheduled","type":"string"}},"type":"object"},"type":{"description":"Type of the Certificate","enum":["uploaded","managed"],"example":"uploaded","type":"string"},"used_by":{"description":"Resources currently using the Certificate","items":{"properties":{"id":{"description":"ID of resource referenced","example":4711,"type":"integer"},"type":{"description":"Type of resource referenced","example":"load_balancer","type":"string"}},"required":["id","type"],"type":"object"},"type":"array"}},"required":["id","name","labels","certificate","created","not_valid_before","not_valid_after","domain_names","fingerprint","used_by"],"title":"Certificate","type":"object"}},"required":["certificate"],"title":"CreateCertificateResponse","type":"object"}}},"description":"The `certificate` key contains the Certificate that was just created. For type `managed` Certificates the `action` key contains the Action that allows for tracking the issuance process. For type `uploaded` Certificates the `action` is always null."}},"summary":"Create a Certificate","tags":["Certificates"]}},"/certificates/{id}":{"delete":{"description":"Deletes a Certificate.","parameters":[{"description":"ID of the resource","in":"path","name":"id","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Certificate deleted"}},"summary":"Delete a Certificate","tags":["Certificates"]},"get":{"description":"Gets a specific Certificate object.","parameters":[{"description":"ID of the resource","in":"path","name":"id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"example":{"certificate":{"certificate":"-----BEGIN CERTIFICATE-----\n...","created":"2025-04-15T13:52:37.540Z","domain_names":["example.com","webmail.example.com","www.example.com"],"fingerprint":"03:c7:55:9b:2a:d1:04:17:09:f6:d0:7f:18:34:63:d4:3e:5f","id":897,"labels":{"env":"dev"},"name":"my website cert","not_valid_after":"2025-04-15T13:52:37.540Z","not_valid_before":"2025-04-15T13:52:37.540Z","status":null,"type":"uploaded","used_by":[{"id":4711,"type":"load_balancer"}]}},"schema":{"properties":{"certificate":{"properties":{"certificate":{"description":"Certificate and chain in PEM format, in order so that each record directly certifies the one preceding","example":"-----BEGIN CERTIFICATE-----\n...","nullable":true,"type":"string"},"created":{"description":"Point in time when the Resource was created (in ISO-8601 format)","example":"2025-04-15T13:52:37.540Z","type":"string"},"domain_names":{"description":"Domains and subdomains covered by the Certificate","example":["example.com","webmail.example.com","www.example.com"],"items":{"type":"string"},"type":"array"},"fingerprint":{"description":"SHA256 fingerprint of the Certificate","example":"03:c7:55:9b:2a:d1:04:17:09:f6:d0:7f:18:34:63:d4:3e:5f","nullable":true,"type":"string"},"id":{"description":"ID of the Resource","example":42,"type":"integer"},"labels":{"additionalProperties":{"type":"string"},"description":"User-defined labels (key-value pairs)","type":"object"},"name":{"description":"Name of the Resource. Must be unique per Project.","example":"my-resource","type":"string"},"not_valid_after":{"description":"Point in time when the Certificate stops being valid (in ISO-8601 format)","example":"2025-04-15T13:52:37.540Z","nullable":true,"type":"string"},"not_valid_before":{"description":"Point in time when the Certificate becomes valid (in ISO-8601 format)","example":"2025-04-15T13:52:37.540Z","nullable":true,"type":"string"},"status":{"description":"Current status of a type `managed` Certificate, always *null* for type `uploaded` Certificates","nullable":true,"properties":{"error":{"description":"If issuance or renewal reports `failed`, this property contains information about what happened","example":null,"nullable":true,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"type":"object"},"issuance":{"description":"Status of the issuance process of the Certificate","enum":["pending","completed","failed"],"example":"valid","type":"string"},"renewal":{"description":"Status of the renewal process of the Certificate.","enum":["scheduled","pending","failed","unavailable"],"example":"scheduled","type":"string"}},"type":"object"},"type":{"description":"Type of the Certificate","enum":["uploaded","managed"],"example":"uploaded","type":"string"},"used_by":{"description":"Resources currently using the Certificate","items":{"properties":{"id":{"description":"ID of resource referenced","example":4711,"type":"integer"},"type":{"description":"Type of resource referenced","example":"load_balancer","type":"string"}},"required":["id","type"],"type":"object"},"type":"array"}},"required":["id","name","labels","certificate","created","not_valid_before","not_valid_after","domain_names","fingerprint","used_by"],"title":"Certificate","type":"object"}},"required":["certificate"],"title":"CertificateResponse","type":"object"}}},"description":