{
 "openapi": "3.1.0",
 "info": {
  "title": "Gyro Public API",
  "version": "2.30.0",
  "summary": "Manage Gyro cloud servers, SSH keys and billing programmatically.",
  "x-summary-tr": "Gyro bulut sunucularınızı, SSH anahtarlarınızı ve faturalarınızı programla yönetin.",
  "contact": {
   "name": "Gyro Hosting",
   "url": "https://www.gyrohosting.com"
  },
  "license": {
   "name": "Proprietary",
   "identifier": "LicenseRef-Gyro-API-Terms"
  }
 },
 "servers": [
  {
   "url": "https://www.gyrohosting.com/api/v1/client",
   "description": "Production"
  }
 ],
 "paths": {
  "/cloud/containers/{id}/egress-ips": {
   "get": {
    "tags": [
     "Containers"
    ],
    "operationId": "getContainerEgressIps",
    "summary": "Egress IPs of a container environment",
    "x-summary-tr": "Kapsayıcı ortamının çıkış IP'leri",
    "x-scope": "services_read",
    "description": "Current public IPv4 addresses the containers reach the internet from - add them to the IP allow list of an external service. Egress IPs of a **dedicated** environment = the public IPs of its own nodes + the shared pool node(s) used while an update rolls out (the new copy starts there for about a minute, then moves back to your node). **Serverless** = the shared sandboxed pool nodes (the pool can grow: a new address can appear). Build machines of Gyro Pipeline are listed separately (`build_ips`). The list changes when the nodes change (plan change, node replacement, pool scaling); the owner is notified (Alerts channels, event `egress`). No IPv6 egress; outbound TCP 25 is closed. A fixed egress address is not offered yet.",
    "x-description-tr": "Kapsayıcıların internete çıktığı güncel IPv4 adresleri - harici bir servisin IP beyaz listesine ekleyin. **Ayrılmış** ortamın çıkış IP'leri = kendi düğümlerinin IP'leri + güncelleme sırasında kullanılan paylaşımlı havuz düğümü (yeni kopya yaklaşık bir dakika orada başlar, sonra düğümünüze döner). **Sunucusuz** = paylaşımlı yalıtılmış havuz düğümleri (havuz büyürse yeni adres eklenebilir). Gyro Pipeline derleme makineleri ayrı listelenir (`build_ips`). Düğümler değişince (paket değişimi, düğüm yenileme, havuz ölçeklemesi) liste değişir ve ortam sahibine bildirim gider (Uyarılar kanalları, `egress` olayı). IPv6 çıkışı yok; TCP 25 kapalı.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      },
      "description": "Service id"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "allOf": [
            {
             "$ref": "#/components/schemas/ContainerEgress"
            },
            {
             "type": "object",
             "properties": {
              "namespace": {
               "type": "string"
              }
             }
            }
           ]
          }
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     }
    },
    "x-cli": {
     "command": "container egress-ips",
     "confirm": false
    }
   }
  }
 },
 "components": {
  "responses": {
   "NotFound": {
    "description": "Not found — also returned for objects owned by someone else",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   }
  },
  "schemas": {
   "Error": {
    "type": "object",
    "required": [
     "error"
    ],
    "properties": {
     "error": {
      "type": "object",
      "required": [
       "code",
       "message"
      ],
      "properties": {
       "code": {
        "type": "string",
        "example": "server_not_found"
       },
       "message": {
        "type": "string"
       },
       "details": {
        "type": "object",
        "additionalProperties": true,
        "description": "Extra data. Limit refusals add the LimitHint fields (`limit_exceeded: true`, `limit_key`, `limit`, `current`, `how_to_increase`, `support_ticket`, `hint`): account limits are raised with a support ticket. Validation errors (length, format) never carry the limit hint.",
        "x-description-tr": "Ek veri. Sınır retlerinde LimitHint alanları gelir: hesap sınırları destek talebiyle artırılır. Doğrulama hataları (uzunluk, biçim) sınır ipucu taşımaz."
       }
      }
     }
    }
   },
   "ContainerEgress": {
    "type": "object",
    "description": "Public IPv4 addresses the containers of the environment reach the internet from (no NAT gateway: traffic leaves from the node the container runs on).",
    "x-description-tr": "Ortamdaki kapsayıcıların internete çıktığı IPv4 adresleri (NAT kapısı yok: trafik kapsayıcının çalıştığı düğümden çıkar).",
    "properties": {
     "mode": {
      "type": "string",
      "enum": [
       "dedicated",
       "serverless"
      ]
     },
     "ips": {
      "type": "array",
      "items": {
       "type": "string",
       "format": "ipv4"
      },
      "description": "Put ALL of them on the IP allow list of an external service.",
      "example": [
       "31.58.248.114",
       "45.87.174.168"
      ]
     },
     "items": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "ip": {
         "type": "string"
        },
        "source": {
         "type": "string",
         "enum": [
          "node",
          "rollout",
          "shared_pool"
         ],
         "description": "node = a node of the dedicated pool (always used); rollout = shared pool where the new copy starts during an update (about a minute) before it moves back; shared_pool = serverless pool node"
        },
        "node": {
         "type": "string",
         "example": "node-1"
        }
       }
      }
     },
     "build_ips": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "Gyro Pipeline build machines (git clone / archive download only)"
     },
     "hash": {
      "type": "string",
      "description": "changes whenever `ips` change (compare to detect a change)"
     },
     "ipv6": {
      "type": "boolean",
      "const": false,
      "description": "no IPv6 egress"
     },
     "note": {
      "type": "string"
     },
     "egress_change": {
      "$ref": "#/components/schemas/ContainerEgressChange"
     },
     "pending_egress_ips": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "new egress IPs announced but not in use for sure yet; add them to your allow lists now"
     },
     "egress_hold_hours": {
      "type": "integer",
      "description": "approval window (0 = off)"
     }
    }
   },
   "ContainerEgressChange": {
    "type": [
     "object",
     "null"
    ],
    "description": "Announced change of the egress IPs (plan change, node added / removed). Null when none.",
    "x-description-tr": "Duyurulan çıkış IP değişikliği (paket değişikliği, düğüm ekleme / çıkarma). Yoksa null.",
    "properties": {
     "id": {
      "type": "string",
      "example": "cm3k9x2a1"
     },
     "kind": {
      "type": "string",
      "enum": [
       "plan",
       "add",
       "remove",
       "mixed"
      ]
     },
     "state": {
      "type": "string",
      "enum": [
       "preparing",
       "pending",
       "approved",
       "applied"
      ],
      "description": "preparing = new addresses not known yet; pending = announced (waits for approval when approval_required); approved = old nodes are being drained; applied = done (kept 24 h)"
     },
     "new_ips": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "remove_ips": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "keep_ips": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "approval_required": {
      "type": "boolean"
     },
     "awaiting_approval": {
      "type": "boolean"
     },
     "hold_hours": {
      "type": "integer"
     },
     "pending_since": {
      "type": "string",
      "format": "date-time"
     },
     "deadline": {
      "type": "string",
      "format": "date-time",
      "description": "the change continues by itself at this time without approval"
     },
     "approved_at": {
      "type": "string"
     },
     "approved_by": {
      "type": "string",
      "enum": [
       "",
       "owner",
       "deadline",
       "automatic"
      ]
     },
     "applied_at": {
      "type": "string"
     }
    }
   }
  }
 },
 "security": [
  {
   "bearerAuth": []
  }
 ]
}