---
title: "Templates — API reference"
description: "Custom templates from your own tr-ist-1 servers (no image upload)"
url: https://www.gyrohosting.com/developers/en/api/templates.html
language: en
openapi: https://www.gyrohosting.com/developers/openapi.json
api_version: 2.30.0
---

# Templates

Custom templates from your own tr-ist-1 servers (no image upload)

Base URL: `https://www.gyrohosting.com/api/v1/client` · OpenAPI: https://www.gyrohosting.com/developers/openapi.json


## GET /cloud/templates

**List your templates** · operationId `listTemplates` · scope `cloud_read` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/listTemplates.json

Billed 0.05 EUR per GB-month of the space the template really uses, hourly from the prepaid balance (through the account's template storage service, opened with the first template). Deleting a template stops its charge. At most 10 templates; visible only in your account. `meta` carries count, max, total_gb and pricing.


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `page` | query | integer |  |
| `limit` | query | integer |  |

### Responses

- **200**: OK
- **404**: Not found — also returned for objects owned by someone else
- **409**: template_limit, template_not_ready, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)

### Examples

```bash
curl -s 'https://www.gyrohosting.com/api/v1/client/cloud/templates' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```bash
gyro template list
```
```hcl
# resource gyro_server_template: https://registry.terraform.io/providers/gyro-hosting/gyro/latest/docs/resources/server_template
resource "gyro_server_template" "golden" {
  server_id   = gyro_server.web.id
  name        = "web-golden"
  description = "nginx + app, 2026-11"
}

resource "gyro_server" "web2" {
  plan          = "standart-2-4"
  region        = "tr-ist-1"
  image         = gyro_server_template.golden.image
  hostname      = "web2.example.com"
  ssh_key_ids   = [gyro_ssh_key.laptop.id]
  confirm_order = true
}
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.get("https://www.gyrohosting.com/api/v1/client/cloud/templates", headers=h, timeout=60)
r.raise_for_status()
print(r.json()["data"])
```
```js
const res = await fetch("https://www.gyrohosting.com/api/v1/client/cloud/templates", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
  },
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```


## GET /cloud/templates/{id}

**Get a template** · operationId `getTemplate` · scope `cloud_read` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/getTemplate.json

Another account's template answers 404.


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `id` (required) | path | integer | Template id |

### Responses

- **200**: OK
- **404**: Not found — also returned for objects owned by someone else
- **409**: template_limit, template_not_ready, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)

### Examples

```bash
curl -s 'https://www.gyrohosting.com/api/v1/client/cloud/templates/12345' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```bash
gyro template get 12345
```
```hcl
# resource gyro_server_template: https://registry.terraform.io/providers/gyro-hosting/gyro/latest/docs/resources/server_template
resource "gyro_server_template" "golden" {
  server_id   = gyro_server.web.id
  name        = "web-golden"
  description = "nginx + app, 2026-11"
}

resource "gyro_server" "web2" {
  plan          = "standart-2-4"
  region        = "tr-ist-1"
  image         = gyro_server_template.golden.image
  hostname      = "web2.example.com"
  ssh_key_ids   = [gyro_ssh_key.laptop.id]
  confirm_order = true
}
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.get("https://www.gyrohosting.com/api/v1/client/cloud/templates/12345", headers=h, timeout=60)
r.raise_for_status()
print(r.json()["data"])
```
```js
const res = await fetch("https://www.gyrohosting.com/api/v1/client/cloud/templates/12345", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
  },
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```


## PATCH /cloud/templates/{id}

**Rename a template** · operationId `updateTemplate` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/updateTemplate.json

Name 1-60 characters (letters, digits, space . _ -).


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `id` (required) | path | integer | Template id |

### Request body

| Field | Type | Description |
|---|---|---|
| `name` | string |  |
| `description` | string |  |

### Responses

- **200**: OK
- **404**: Not found — also returned for objects owned by someone else
- **409**: template_limit, template_not_ready, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)

### Examples

```bash
curl -s -X PATCH 'https://www.gyrohosting.com/api/v1/client/cloud/templates/12345' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "string", "description": "string"}'
```
```bash
gyro template update 12345 --help    # all flags
```
```hcl
# resource gyro_server_template: https://registry.terraform.io/providers/gyro-hosting/gyro/latest/docs/resources/server_template
resource "gyro_server_template" "golden" {
  server_id   = gyro_server.web.id
  name        = "web-golden"
  description = "nginx + app, 2026-11"
}

resource "gyro_server" "web2" {
  plan          = "standart-2-4"
  region        = "tr-ist-1"
  image         = gyro_server_template.golden.image
  hostname      = "web2.example.com"
  ssh_key_ids   = [gyro_ssh_key.laptop.id]
  confirm_order = true
}
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.patch("https://www.gyrohosting.com/api/v1/client/cloud/templates/12345", headers=h, json={"name": "string", "description": "string"}, timeout=60)
r.raise_for_status()
print(r.json()["data"])
```
```js
const res = await fetch("https://www.gyrohosting.com/api/v1/client/cloud/templates/12345", {
  method: "PATCH",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"name": "string", "description": "string"}),
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```


## DELETE /cloud/templates/{id}

**Delete a template** · operationId `deleteTemplate` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/deleteTemplate.json

Permanent. Servers created from it are not affected; the charge stops from the next hour.


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `id` (required) | path | integer | Template id |

### Responses

- **202**: OK
- **404**: Not found — also returned for objects owned by someone else
- **409**: template_limit, template_not_ready, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)

### Examples

```bash
curl -s -X DELETE 'https://www.gyrohosting.com/api/v1/client/cloud/templates/12345' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```bash
gyro template delete 12345
```
```hcl
# resource gyro_server_template: https://registry.terraform.io/providers/gyro-hosting/gyro/latest/docs/resources/server_template
resource "gyro_server_template" "golden" {
  server_id   = gyro_server.web.id
  name        = "web-golden"
  description = "nginx + app, 2026-11"
}

resource "gyro_server" "web2" {
  plan          = "standart-2-4"
  region        = "tr-ist-1"
  image         = gyro_server_template.golden.image
  hostname      = "web2.example.com"
  ssh_key_ids   = [gyro_ssh_key.laptop.id]
  confirm_order = true
}
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.delete("https://www.gyrohosting.com/api/v1/client/cloud/templates/12345", headers=h, timeout=60)
r.raise_for_status()
print(r.json()["data"])
```
```js
const res = await fetch("https://www.gyrohosting.com/api/v1/client/cloud/templates/12345", {
  method: "DELETE",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
  },
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```


## POST /cloud/servers/{id}/templates

**Capture a server as a template** · operationId `createTemplate` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/createTemplate.json

Billed 0.05 EUR per GB-month of the space the template really uses, hourly from the prepaid balance (through the account's template storage service, opened with the first template). Deleting a template stops its charge. At most 10 templates; visible only in your account. Only the root disk is copied. `mode: snapshot` (default) keeps the server running (file system frozen briefly via a temporary snapshot); `mode: shutdown` stops the server, copies it and starts it again. Servers created from the template get a new host name, IP, root password, SSH host keys and machine id (cloud-init); your users, files and settings stay. Linux servers only. Ready in about a minute (`status` creating -> ready).


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `id` (required) | path | integer | Server id (tr-ist-1) |

### Request body

| Field | Type | Description |
|---|---|---|
| `name` | string |  |
| `description` | string |  |
| `mode` | string (snapshot, shutdown) |  |

### Responses

- **202**: OK
- **404**: Not found — also returned for objects owned by someone else
- **409**: template_limit, template_not_ready, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)

### Examples

```bash
curl -s -X POST 'https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/templates' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "string", "description": "string", "mode": "snapshot"}'
```
```bash
gyro template create 12345 --help    # all flags
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.post("https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/templates", headers=h, json={"name": "string", "description": "string", "mode": "snapshot"}, timeout=60)
r.raise_for_status()
print(r.json()["data"])
```
```js
const res = await fetch("https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/templates", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"name": "string", "description": "string", "mode": "snapshot"}),
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```


## POST /cloud/templates/{id}/servers

**New server from a template** · operationId `createServerFromTemplate` · scope `cloud_order` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/createServerFromTemplate.json

A normal prepaid tr-ist-1 order (24-hour balance rule, account limits) installed from the template. `product_id` (or `plan`) from GET /cloud/products?region=tr-ist-1; its disk must be at least the template `min_disk_gb`. Send `"confirm": true` and an `Idempotency-Key` header (`dry_run` for a quote).


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `id` (required) | path | integer | Template id |

### Request body

| Field | Type | Description |
|---|---|---|
| `product_id` | integer |  |
| `plan` | string |  |
| `hostname` | string |  |
| `ssh_keys` | array<integer> |  |
| `user_data` | string |  |
| `confirm` | boolean |  |
| `dry_run` | boolean |  |
| `project_id` | integer | Optional project for the new service(s) (0 = default project). Checked before the order: unknown id = 404 `project_not_found` (GyroAPI order endpoints) or 422 `checkout_blocked` with `[project_not_found]` (POST /orders). |

### Responses

- **202**: OK
- **404**: Not found — also returned for objects owned by someone else
- **409**: template_limit, template_not_ready, busy
- **422**: confirm_required | limit_exceeded (new-account limit of the prepaid cloud; details = LimitHint, raise it with a support ticket) | validation errors

### Examples

```bash
curl -s -X POST 'https://www.gyrohosting.com/api/v1/client/cloud/templates/12345/servers' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"product_id": 1, "plan": "string", "hostname": "string", "ssh_keys": [1], "user_data": "string", "confirm": true, "dry_run": true, "project_id": 1}'
```
```bash
gyro template deploy 12345 --help    # all flags
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.post("https://www.gyrohosting.com/api/v1/client/cloud/templates/12345/servers", headers=h, json={"product_id": 1, "plan": "string", "hostname": "string", "ssh_keys": [1], "user_data": "string", "confirm": True, "dry_run": True, "project_id": 1}, timeout=60)
r.raise_for_status()
print(r.json()["data"])
```
```js
const res = await fetch("https://www.gyrohosting.com/api/v1/client/cloud/templates/12345/servers", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"product_id": 1, "plan": "string", "hostname": "string", "ssh_keys": [1], "user_data": "string", "confirm": true, "dry_run": true, "project_id": 1}),
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```


## POST /cloud/templates/{id}/rebuild

**Reinstall a server from a template** · operationId `rebuildFromTemplate` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/rebuildFromTemplate.json

Overwrites the root disk of one of your tr-ist-1 servers with the template (its disk must be at least `min_disk_gb`); the server's SSH keys are installed again and a new root password is returned (withheld when an Idempotency-Key is sent). Needs `"confirm": true`.


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `id` (required) | path | integer | Template id |

### Request body

| Field | Type | Description |
|---|---|---|
| `server_id` (required) | integer |  |
| `user_data` | string |  |
| `confirm` (required) | boolean |  |

### Responses

- **202**: OK
- **404**: Not found — also returned for objects owned by someone else
- **409**: template_limit, template_not_ready, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)

### Examples

```bash
curl -s -X POST 'https://www.gyrohosting.com/api/v1/client/cloud/templates/12345/rebuild' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"server_id": 1, "user_data": "string", "confirm": true}'
```
```bash
gyro template rebuild 12345 --help    # all flags
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.post("https://www.gyrohosting.com/api/v1/client/cloud/templates/12345/rebuild", headers=h, json={"server_id": 1, "user_data": "string", "confirm": True}, timeout=60)
r.raise_for_status()
print(r.json()["data"])
```
```js
const res = await fetch("https://www.gyrohosting.com/api/v1/client/cloud/templates/12345/rebuild", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"server_id": 1, "user_data": "string", "confirm": true}),
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```
