API keys
Sub-account keys narrowed to services, actions or a reseller end-customer. Only GyroAPI /cloud routes accept them.
#GET/cloud/keys
List sub-account keys (never shows tokens)Scope: keyslistApiKeysOpenAPI for this operation
Responses
| 200 | Keys — data: array<ApiKey> |
| 403 | Key lacks the scope, IP not allowed, or feature disabled |
Examples
curl -s 'https://www.gyrohosting.com/api/v1/client/cloud/keys' \
-H "Authorization: Bearer $GYRO_TOKEN"gyro key list# resource gyro_api_key: https://registry.terraform.io/providers/gyro-hosting/gyro/latest/docs/resources/api_key
# A key for the reseller's end-customer: sees only Acme's services, cannot reach billing
resource "gyro_api_key" "acme_ci" {
name = "acme-ci"
customer_id = tonumber(gyro_reseller_customer.acme.id)
scopes = ["cloud_read", "cloud_write", "services_read", "services_write"]
actions = ["reboot", "poweron", "snapshots:*"]
rate_limit = 60
}
output "acme_token" {
value = gyro_api_key.acme_ci.token
sensitive = true
}import os, uuid, requests
h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.get("https://www.gyrohosting.com/api/v1/client/cloud/keys", headers=h, timeout=60)
r.raise_for_status()
print(r.json()["data"])const res = await fetch("https://www.gyrohosting.com/api/v1/client/cloud/keys", {
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}`);#POST/cloud/keys
Create a sub-account key (token returned once)Scope: keyscreateApiKeyOpenAPI for this operation
Request body
| Field | Type | Description |
|---|---|---|
name required | string | |
scopes | array<string (cloud_read, cloud_write, cloud_order, cloud_delete, services_read, services_write, webhooks)> | |
services | array<integer> | Optional service allow list |
actions | array<string> | Optional action allow list: server actions (reboot) or tool:action / tool:* / method:name |
ips | array<string> | |
rate_limit | integer | Requests per minute (<= your own limit; 0 = default) |
Responses
| 201 | Created — data: object |
| 403 | Key lacks the scope, IP not allowed, or feature disabled |
| 422 | Validation or business rule failure (confirm_required, invalid_image, tool_action_failed ...) |
Examples
curl -s -X POST 'https://www.gyrohosting.com/api/v1/client/cloud/keys' \
-H "Authorization: Bearer $GYRO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "ci-reboot-only", "scopes": ["cloud_read", "cloud_write"], "services": [47466], "actions": ["reboot", "poweron"], "ips": ["203.0.113.10"], "rate_limit": 30}'gyro key create --help # all flags# resource gyro_api_key: https://registry.terraform.io/providers/gyro-hosting/gyro/latest/docs/resources/api_key
# A key for the reseller's end-customer: sees only Acme's services, cannot reach billing
resource "gyro_api_key" "acme_ci" {
name = "acme-ci"
customer_id = tonumber(gyro_reseller_customer.acme.id)
scopes = ["cloud_read", "cloud_write", "services_read", "services_write"]
actions = ["reboot", "poweron", "snapshots:*"]
rate_limit = 60
}
output "acme_token" {
value = gyro_api_key.acme_ci.token
sensitive = true
}import os, uuid, requests
h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.post("https://www.gyrohosting.com/api/v1/client/cloud/keys", headers=h, json={"name": "ci-reboot-only", "scopes": ["cloud_read", "cloud_write"], "services": [47466], "actions": ["reboot", "poweron"], "ips": ["203.0.113.10"], "rate_limit": 30}, timeout=60)
r.raise_for_status()
print(r.json()["data"])const res = await fetch("https://www.gyrohosting.com/api/v1/client/cloud/keys", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "ci-reboot-only", "scopes": ["cloud_read", "cloud_write"], "services": [47466], "actions": ["reboot", "poweron"], "ips": ["203.0.113.10"], "rate_limit": 30}),
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);#DELETE/cloud/keys/{id}
Delete a sub-account keyScope: keysdeleteApiKeyOpenAPI for this operation
Parameters
| Field | in | Type | Description |
|---|---|---|---|
id required | path | integer |
Responses
| 200 | Deleted |
| 404 | Not found — also returned for objects owned by someone else |
Examples
curl -s -X DELETE 'https://www.gyrohosting.com/api/v1/client/cloud/keys/12345' \
-H "Authorization: Bearer $GYRO_TOKEN"gyro key delete 12345# resource gyro_api_key: https://registry.terraform.io/providers/gyro-hosting/gyro/latest/docs/resources/api_key
# A key for the reseller's end-customer: sees only Acme's services, cannot reach billing
resource "gyro_api_key" "acme_ci" {
name = "acme-ci"
customer_id = tonumber(gyro_reseller_customer.acme.id)
scopes = ["cloud_read", "cloud_write", "services_read", "services_write"]
actions = ["reboot", "poweron", "snapshots:*"]
rate_limit = 60
}
output "acme_token" {
value = gyro_api_key.acme_ci.token
sensitive = true
}import os, uuid, requests
h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.delete("https://www.gyrohosting.com/api/v1/client/cloud/keys/12345", headers=h, timeout=60)
r.raise_for_status()
print(r.json()["data"])const res = await fetch("https://www.gyrohosting.com/api/v1/client/cloud/keys/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}`);