---
title: "Private networks — API reference"
description: "Private networks (VPC) for Gyro Cloud Istanbul (tr-ist-1) servers: subnets, private network cards, turning a server's public IPv4 off, and the VPC gat"
url: https://www.gyrohosting.com/developers/en/api/private-networks.html
language: en
openapi: https://www.gyrohosting.com/developers/openapi.json
api_version: 2.30.0
---

# Private networks

Private networks (VPC) for Gyro Cloud Istanbul (tr-ist-1) servers: subnets, private network cards, turning a server's public IPv4 off, and the VPC gateway (NAT internet access, port forwarding, inter-subnet rule). VPCs, subnets and private traffic are free; the gateway is billed hourly from the prepaid balance while it is on (4.99 EUR per month at most).

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


## GET /cloud/vpcs

**List private networks** · operationId `listVpcs` · scope `cloud_read` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/listVpcs.json

tr-ist-1 only. Limits (GET /cloud/vpcs `limits`, raised with a support ticket): 3 VPCs per account, 4 subnets per VPC, 3 private cards per server, 20 port forwards per VPC; a server is attached to one VPC at a time (to several of its subnets). Another account's object answers 404. Also returns `limits` and `pricing`.


### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.get("https://www.gyrohosting.com/api/v1/client/cloud/vpcs", 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/vpcs", {
  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/vpcs

**Create a private network** · operationId `createVpc` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/createVpc.json

tr-ist-1 only. Limits (GET /cloud/vpcs `limits`, raised with a support ticket): 3 VPCs per account, 4 subnets per VPC, 3 private cards per server, 20 port forwards per VPC; a server is attached to one VPC at a time (to several of its subnets). Another account's object answers 404. Private range /16 to /24 inside 10.0.0.0/8, 172.16.0.0/12 or 192.168.0.0/16; the network address must be given (10.10.0.0/16, not 10.10.0.5/16). Reserved by the platform: 10.42.0.0/16, 10.43.0.0/16, 10.200.0.0/16, 10.250.0.0/16, 10.255.0.0/16. The first subnet is created with it: `subnet.cidr` or, when left out, the first /24 of the range (name `default`). Free.


### Request body

| Field | Type | Description |
|---|---|---|
| `name` (required) | string |  |
| `cidr` (required) | string |  |
| `project_id` | integer |  |
| `subnet` | object |  |
| `subnet.name` | string |  |
| `subnet.cidr` | string |  |

### Responses

- **201**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X POST 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "string", "cidr": "10.10.0.0/16", "project_id": 1, "subnet": {"name": "string", "cidr": "10.10.1.0/24"}}'
```
```python
import os, uuid, requests

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


## GET /cloud/vpcs/{vpc_id}

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

Subnets, attached servers and the gateway.


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `vpc_id` (required) | path | string | VPC id (from GET /cloud/vpcs) |

### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.get("https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1", 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/vpcs/1", {
  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/vpcs/{vpc_id}

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

Only the name changes (the range never changes).


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `vpc_id` (required) | path | string | VPC id (from GET /cloud/vpcs) |

### Request body

| Field | Type | Description |
|---|---|---|
| `name` (required) | string |  |

### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X PATCH 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "string"}'
```
```python
import os, uuid, requests

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


## DELETE /cloud/vpcs/{vpc_id}

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

Permanent. Detach the server cards and delete the port forwards first (409 `vpc_in_use`); an open gateway is turned off. Needs `"confirm": true` (body or query).


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `vpc_id` (required) | path | string | VPC id (from GET /cloud/vpcs) |
| `confirm` | query | boolean |  |

### Request body

| Field | Type | Description |
|---|---|---|
| `confirm` | boolean |  |

### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X DELETE 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"confirm": true}'
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.delete("https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1", headers=h, json={"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/vpcs/1", {
  method: "DELETE",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"confirm": true}),
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```


## GET /cloud/vpcs/{vpc_id}/subnets

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




### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `vpc_id` (required) | path | string | VPC id (from GET /cloud/vpcs) |

### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/subnets' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.get("https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/subnets", 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/vpcs/1/subnets", {
  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/vpcs/{vpc_id}/subnets

**Add a subnet** · operationId `createVpcSubnet` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/createVpcSubnet.json

/20 to /28 inside the VPC range, not overlapping another subnet. Give `cidr`, or `prefix` (default 24) for the next free range. In every subnet .1 is the gateway; .0-.4 and the last address are reserved.


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `vpc_id` (required) | path | string | VPC id (from GET /cloud/vpcs) |

### Request body

| Field | Type | Description |
|---|---|---|
| `name` (required) | string |  |
| `cidr` | string |  |
| `prefix` | integer |  |

### Responses

- **201**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X POST 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/subnets' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "string", "cidr": "string", "prefix": 1}'
```
```python
import os, uuid, requests

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


## DELETE /cloud/vpcs/{vpc_id}/subnets/{subnet_id}

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

Refused while cards are attached or a port forward targets it (409 `subnet_in_use`); the last subnet cannot be deleted (delete the VPC).


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `vpc_id` (required) | path | string | VPC id (from GET /cloud/vpcs) |
| `subnet_id` (required) | path | string | Subnet id |

### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X DELETE 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/subnets/1' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.delete("https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/subnets/1", 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/vpcs/1/subnets/1", {
  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}`);
```


## GET /cloud/vpcs/{vpc_id}/gateway

**Get the VPC gateway** · operationId `getVpcGateway` · scope `cloud_read` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/getVpcGateway.json

The gateway gives private-only servers internet access (NAT), port forwarding and the inter-subnet rule. While it is on it is billed hourly from the prepaid balance (`monthly_eur` / 672, at least 1 hour, never more than `monthly_eur` a month) and needs at least one prepaid tr-ist-1 server on the account (409 `no_billing_server`). Turning it off releases its public IP; refused while port forwards exist, or while private-only servers use it (409 `gateway_in_use`, repeat with `allow_no_egress: true`). Outgoing connections are logged as required by Turkish Law No. 5651 (2 years). 


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `vpc_id` (required) | path | string | VPC id (from GET /cloud/vpcs) |

### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/gateway' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.get("https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/gateway", 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/vpcs/1/gateway", {
  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}`);
```


## PUT /cloud/vpcs/{vpc_id}/gateway

**Turn the VPC gateway on/off and change its settings** · operationId `setVpcGateway` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/setVpcGateway.json

The gateway gives private-only servers internet access (NAT), port forwarding and the inter-subnet rule. While it is on it is billed hourly from the prepaid balance (`monthly_eur` / 672, at least 1 hour, never more than `monthly_eur` a month) and needs at least one prepaid tr-ist-1 server on the account (409 `no_billing_server`). Turning it off releases its public IP; refused while port forwards exist, or while private-only servers use it (409 `gateway_in_use`, repeat with `allow_no_egress: true`). Outgoing connections are logged as required by Turkish Law No. 5651 (2 years). Only the given fields change.


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `vpc_id` (required) | path | string | VPC id (from GET /cloud/vpcs) |

### Request body

| Field | Type | Description |
|---|---|---|
| `enabled` | boolean |  |
| `nat` | boolean |  |
| `inter_subnet` | string (allow, deny) |  |
| `allow_no_egress` | boolean |  |

### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X PUT 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/gateway' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"enabled": true, "nat": true, "inter_subnet": "allow", "allow_no_egress": true}'
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.put("https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/gateway", headers=h, json={"enabled": True, "nat": True, "inter_subnet": "allow", "allow_no_egress": True}, timeout=60)
r.raise_for_status()
print(r.json()["data"])
```
```js
const res = await fetch("https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/gateway", {
  method: "PUT",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"enabled": true, "nat": true, "inter_subnet": "allow", "allow_no_egress": true}),
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```


## GET /cloud/vpcs/{vpc_id}/port-forwards

**List port forwards** · operationId `listVpcPortForwards` · scope `cloud_read` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/listVpcPortForwards.json




### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `vpc_id` (required) | path | string | VPC id (from GET /cloud/vpcs) |

### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/port-forwards' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.get("https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/port-forwards", 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/vpcs/1/port-forwards", {
  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/vpcs/{vpc_id}/port-forwards

**Forward a public port of the gateway** · operationId `createVpcPortForward` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/createVpcPortForward.json

public_ip:public_port of the gateway -> target_ip:target_port inside the VPC. The gateway must be on (409 `gateway_disabled`); one forward per protocol + public port; at most 20.


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `vpc_id` (required) | path | string | VPC id (from GET /cloud/vpcs) |

### Request body

| Field | Type | Description |
|---|---|---|
| `protocol` (required) | string (tcp, udp) |  |
| `public_port` (required) | integer |  |
| `target_ip` (required) | string |  |
| `target_port` (required) | integer |  |

### Responses

- **201**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X POST 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/port-forwards' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"protocol": "tcp", "public_port": 1, "target_ip": "string", "target_port": 1}'
```
```python
import os, uuid, requests

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


## DELETE /cloud/vpcs/{vpc_id}/port-forwards/{pf_id}

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




### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `vpc_id` (required) | path | string | VPC id (from GET /cloud/vpcs) |
| `pf_id` (required) | path | string | Port forward id |

### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X DELETE 'https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/port-forwards/1' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.delete("https://www.gyrohosting.com/api/v1/client/cloud/vpcs/1/port-forwards/1", 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/vpcs/1/port-forwards/1", {
  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}`);
```


## GET /cloud/servers/{id}/nics

**List the server's private network cards** · operationId `listServerNics` · scope `cloud_read` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/listServerNics.json

Private network cards of a tr-ist-1 server. Attaching is hot (no restart): the card is ready in about 10-60 s on a running server (`state` attaching -> ready); on a stopped server the settings apply at boot. A server can join one VPC at a time (409 `other_vpc`), at most 3 cards. `ip` empty = automatic. 


### Parameters

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

### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s 'https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/nics' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.get("https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/nics", 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/servers/12345/nics", {
  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/servers/{id}/nics

**Attach the server to a subnet** · operationId `attachServerNic` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/attachServerNic.json

Private network cards of a tr-ist-1 server. Attaching is hot (no restart): the card is ready in about 10-60 s on a running server (`state` attaching -> ready); on a stopped server the settings apply at boot. A server can join one VPC at a time (409 `other_vpc`), at most 3 cards. `ip` empty = automatic. 


### Parameters

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

### Request body

| Field | Type | Description |
|---|---|---|
| `subnet_id` (required) | string |  |
| `ip` | string |  |

### Responses

- **202**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X POST 'https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/nics' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"subnet_id": "string", "ip": "string"}'
```
```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/nics", headers=h, json={"subnet_id": "string", "ip": "string"}, 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/nics", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"subnet_id": "string", "ip": "string"}),
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```


## DELETE /cloud/servers/{id}/nics/{nic_id}

**Detach a private network card** · operationId `detachServerNic` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/detachServerNic.json

The address is held for 10 minutes. While the public IP is off the last card cannot be detached (409 `last_network`).


### Parameters

| Field | in | Type | Description |
|---|---|---|---|
| `id` (required) | path | integer | Server id (tr-ist-1) |
| `nic_id` (required) | path | string | Network card id (from GET /cloud/servers/{id}/nics) |

### Responses

- **202**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X DELETE 'https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/nics/1' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.delete("https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/nics/1", 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/servers/12345/nics/1", {
  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}`);
```


## GET /cloud/servers/{id}/public-ip

**Public IPv4 state** · operationId `getServerPublicIp` · scope `cloud_read` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/getServerPublicIp.json

Turning the public IPv4 off makes the server reachable only from its VPC, through a gateway port forward or with the web console (which always works). Confirm with the server's current IP (`confirm_ip`). Needs a ready private card (409 `no_private_network`) and no additional IPv4 (409 `extra_ips`). If the VPC gateway (NAT) is off the server loses internet access: refused with 409 `no_egress` unless `allow_no_egress: true`. The address stays reserved for the server; turning it on brings the same IP. 


### Parameters

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

### Responses

- **200**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s 'https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/public-ip' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.get("https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/public-ip", 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/servers/12345/public-ip", {
  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/servers/{id}/public-ip

**Turn the public IPv4 on** · operationId `enableServerPublicIp` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/enableServerPublicIp.json

Brings the same address back.


### Parameters

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

### Responses

- **202**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X POST 'https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/public-ip' \
  -H "Authorization: Bearer $GYRO_TOKEN"
```
```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/public-ip", 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/servers/12345/public-ip", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
  },
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```


## DELETE /cloud/servers/{id}/public-ip

**Turn the public IPv4 off** · operationId `disableServerPublicIp` · scope `cloud_write` · OpenAPI fragment: https://www.gyrohosting.com/developers/spec/ops/disableServerPublicIp.json

Turning the public IPv4 off makes the server reachable only from its VPC, through a gateway port forward or with the web console (which always works). Confirm with the server's current IP (`confirm_ip`). Needs a ready private card (409 `no_private_network`) and no additional IPv4 (409 `extra_ips`). If the VPC gateway (NAT) is off the server loses internet access: refused with 409 `no_egress` unless `allow_no_egress: true`. The address stays reserved for the server; turning it on brings the same IP. 


### Parameters

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

### Request body

| Field | Type | Description |
|---|---|---|
| `confirm_ip` (required) | string |  |
| `allow_no_egress` | boolean |  |

### Responses

- **202**: OK
- **403**: not_available (private networks are not enabled for this account yet) / forbidden (key limited to some servers)
- **404**: Not found — also returned for objects owned by someone else
- **409**: conflict: limit_exceeded, vpc_in_use, subnet_in_use, last_subnet, gateway_disabled, gateway_in_use, port_in_use, already_attached, other_vpc, extra_ips, no_private_network, no_egress, already_off, already_on, last_network, no_billing_server, suspended, busy
- **422**: Validation or business rule failure (`confirm_required`, `invalid_image`, `tool_action_failed` ...)
- **503**: capacity / pool_exhausted (try again later)

### Examples

```bash
curl -s -X DELETE 'https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/public-ip' \
  -H "Authorization: Bearer $GYRO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"confirm_ip": "string", "allow_no_egress": true}'
```
```python
import os, uuid, requests

h = {"Authorization": "Bearer " + os.environ["GYRO_TOKEN"]}
r = requests.delete("https://www.gyrohosting.com/api/v1/client/cloud/servers/12345/public-ip", headers=h, json={"confirm_ip": "string", "allow_no_egress": True}, 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/public-ip", {
  method: "DELETE",
  headers: {
    "Authorization": `Bearer ${process.env.GYRO_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"confirm_ip": "string", "allow_no_egress": true}),
});
const { data, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
```
