{
  "openapi": "3.0.3",
  "info": {
    "title": "GPUcloud API",
    "description": "REST API of GPUcloud.ca: GPU plans, GPU servers (deploy, power actions, metrics, firewall), SSH keys and API keys. All prices are in CAD. Authenticate with a REST API key: `Authorization: Bearer <key>`. AI agents should use the MCP endpoint (https://gpucloud.ca/api/mcp) with an MCP key instead. REST keys (prefix gpu_) are created in the console, expire after 90 days and are either full access or read-only (GET only; a read-only key gets 401 on any other method). Write requests (POST, PUT, DELETE) must also send the header `Origin: https://gpucloud.ca`, otherwise they get 403. Developer guide: https://gpucloud.ca/en/developers",
    "version": "1.1.1",
    "contact": {
      "name": "GPUcloud Support",
      "url": "https://gpucloud.ca",
      "email": "info@gpucloud.ca"
    }
  },
  "servers": [
    {
      "url": "https://gpucloud.ca/api",
      "description": "Production"
    }
  ],
  "security": [],
  "paths": {
    "/v1/gpu": {
      "get": {
        "summary": "List GPU Plans",
        "description": "Returns every GPU machine size with the prices of the authenticated account (CAD per machine) and its current availability. Requires an API key. For anonymous availability, use GET /v1/availability.",
        "operationId": "listGpuPlans",
        "tags": [
          "GPU Plans"
        ],
        "responses": {
          "200": {
            "description": "List of GPU plans",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/GpuPlan"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "gpu-l40",
                      "name": "NVIDIA L40",
                      "gpu": "1x NVIDIA L40 (48 GB GDDR6)",
                      "gpuModel": "NVIDIA L40",
                      "gpuCount": 1,
                      "spot": false,
                      "hourlyOnly": false,
                      "specs": {
                        "vcores": 28,
                        "ram": 58,
                        "storage": 100,
                        "localStorage": 725,
                        "storageType": "NVMe"
                      },
                      "pricing": {
                        "hourly": 1.34,
                        "monthly": 941.7,
                        "annual": 941.7,
                        "currency": "CAD"
                      },
                      "priceOnRequest": false,
                      "available": true,
                      "purchasable": true,
                      "autoProvisioning": true,
                      "eligibility": "deployable"
                    },
                    {
                      "id": "gpu-l40-x2",
                      "name": "NVIDIA L40 × 2",
                      "gpu": "2x NVIDIA L40 (48 GB GDDR6)",
                      "gpuModel": "NVIDIA L40",
                      "gpuCount": 2,
                      "spot": false,
                      "hourlyOnly": false,
                      "specs": {
                        "vcores": 60,
                        "ram": 116,
                        "storage": 100,
                        "localStorage": 1550,
                        "storageType": "NVMe"
                      },
                      "pricing": {
                        "hourly": 2.68,
                        "monthly": 1876.1,
                        "annual": 1876.1,
                        "currency": "CAD"
                      },
                      "priceOnRequest": false,
                      "available": true,
                      "purchasable": true,
                      "autoProvisioning": true,
                      "eligibility": "deployable"
                    },
                    {
                      "id": "gpu-l40-spot",
                      "name": "NVIDIA L40 Spot (interruptible)",
                      "gpu": "1x NVIDIA L40 (48 GB GDDR6)",
                      "gpuModel": "NVIDIA L40",
                      "gpuCount": 1,
                      "spot": true,
                      "hourlyOnly": true,
                      "specs": {
                        "vcores": 28,
                        "ram": 58,
                        "storage": 100,
                        "localStorage": 725,
                        "storageType": "NVMe"
                      },
                      "pricing": {
                        "hourly": 1.07,
                        "monthly": null,
                        "annual": null,
                        "currency": "CAD"
                      },
                      "priceOnRequest": false,
                      "available": true,
                      "purchasable": true,
                      "autoProvisioning": true,
                      "eligibility": "deployable"
                    },
                    {
                      "id": "gpu-h200-sxm-x8",
                      "name": "NVIDIA H200 SXM × 8",
                      "gpu": "8x NVIDIA H200 SXM (141 GB HBM3e)",
                      "gpuModel": "NVIDIA H200 SXM",
                      "gpuCount": 8,
                      "spot": false,
                      "hourlyOnly": false,
                      "specs": {
                        "vcores": 176,
                        "ram": 1800,
                        "storage": 100,
                        "localStorage": 48000,
                        "storageType": "NVMe"
                      },
                      "pricing": null,
                      "priceOnRequest": true,
                      "available": false,
                      "purchasable": false,
                      "autoProvisioning": false,
                      "eligibility": "contact"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/v1/availability": {
      "get": {
        "summary": "Public GPU availability",
        "description": "PUBLIC, no authentication. Aggregated availability per GPU model and machine size (available true / false), refreshed at most every 60 seconds (Cache-Control: max-age=60). Rate limited to 60 requests per minute per IP. No prices: see /v1/gpu or https://gpucloud.ca/llms.txt.",
        "operationId": "getPublicAvailability",
        "tags": [
          "GPU Plans"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Availability per model and size",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicAvailability"
                    }
                  }
                },
                "example": {
                  "data": {
                    "region": "canada-montreal",
                    "updatedAt": "2026-09-28T12:00:00.000Z",
                    "models": [
                      {
                        "slug": "h100",
                        "name": "NVIDIA H100 PCIe",
                        "sizes": [
                          {
                            "id": "gpu-h100",
                            "gpuCount": 1,
                            "spot": false,
                            "available": true,
                            "priceOnRequest": false
                          },
                          {
                            "id": "gpu-h100-x2",
                            "gpuCount": 2,
                            "spot": false,
                            "available": false,
                            "priceOnRequest": false
                          }
                        ]
                      },
                      {
                        "slug": "h200",
                        "name": "NVIDIA H200 SXM",
                        "sizes": [
                          {
                            "id": "gpu-h200-sxm-x8",
                            "gpuCount": 8,
                            "spot": false,
                            "available": false,
                            "priceOnRequest": true
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/servers": {
      "get": {
        "summary": "List Servers",
        "description": "List all GPU servers owned by the authenticated user.",
        "operationId": "listServers",
        "tags": [
          "Servers"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of servers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ServerSummary"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "clxyz123456",
                      "name": "gpu-abc12345-1719000000000",
                      "status": "ACTIVE",
                      "gpu": "L40",
                      "specs": {
                        "vcores": 28,
                        "ram": 58,
                        "storage": 100
                      },
                      "ipv4": "1.2.3.4",
                      "region": "canada-montreal",
                      "monthlyCost": 941.7,
                      "createdAt": "2026-06-24T12:00:00.000Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "summary": "Create Server",
        "description": "Deploy a new GPU server. A public IP address is assigned once the server is running. The first hour (hourly billing) is taken from the credit balance.",
        "operationId": "createServer",
        "tags": [
          "Servers"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateServerRequest"
              },
              "example": {
                "productId": "gpu-l40",
                "sshKeyId": "clxyz123456",
                "name": "my-ml-server",
                "region": "canada-montreal"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Server created and provisioning started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ServerCreated"
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "clxyz123456",
                    "name": "gpu-abc12345-1719000000000",
                    "status": "PROVISIONING",
                    "gpu": "L40"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "409": {
            "description": "GPU not available in the requested region",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "GPU not currently available in this region"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/servers/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Server ID"
        }
      ],
      "get": {
        "summary": "Get Server",
        "description": "Get full details for a specific server.",
        "operationId": "getServer",
        "tags": [
          "Servers"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Server details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ServerDetail"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "summary": "Delete Server",
        "description": "Destroy a GPU server and all its data (irreversible).",
        "operationId": "deleteServer",
        "tags": [
          "Servers"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Server deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "example": "DELETED"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/servers/{id}/actions": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Server ID"
        }
      ],
      "post": {
        "summary": "Server Action",
        "description": "Execute a power action on the server: start, stop (a stopped server is still billed), reboot, hibernate (no longer billed, public IP released) or hibernate-restore (a new public IP is assigned).",
        "operationId": "serverAction",
        "tags": [
          "Servers"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActionRequest"
              },
              "example": {
                "action": "reboot"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Action accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "action": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "example": "accepted"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/servers/{id}/metrics": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Server ID"
        }
      ],
      "get": {
        "summary": "Server Metrics",
        "description": "Get CPU, RAM, and network metrics for a server.",
        "operationId": "getServerMetrics",
        "tags": [
          "Metrics"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Server metrics",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Metrics"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Server not yet provisioned",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/servers/{id}/firewall": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Server ID"
        }
      ],
      "get": {
        "summary": "List Firewall Rules",
        "description": "List the firewall rules of a server.",
        "operationId": "listFirewallRules",
        "tags": [
          "Firewall"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of firewall rules",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FirewallRule"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "summary": "Add Firewall Rule",
        "description": "Add a firewall rule to a server.",
        "operationId": "addFirewallRule",
        "tags": [
          "Firewall"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateFirewallRuleRequest"
              },
              "example": {
                "direction": "ingress",
                "protocol": "tcp",
                "portRangeMin": 8080,
                "portRangeMax": 8080,
                "remoteIpPrefix": "0.0.0.0/0"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Firewall rule created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FirewallRule"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "summary": "Delete Firewall Rule",
        "description": "Remove a firewall rule from a server.",
        "operationId": "deleteFirewallRule",
        "tags": [
          "Firewall"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Firewall rule deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "ruleId": {
                          "type": "integer"
                        },
                        "status": {
                          "type": "string",
                          "example": "deleted"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ruleId"
                ],
                "properties": {
                  "ruleId": {
                    "type": "integer",
                    "description": "Id of the rule (from GET /servers/{id}/firewall)"
                  }
                }
              },
              "example": {
                "ruleId": 123
              }
            }
          }
        }
      }
    },
    "/settings/ssh-keys": {
      "get": {
        "summary": "List SSH Keys",
        "description": "List all SSH keys for the authenticated user.",
        "operationId": "listSshKeys",
        "tags": [
          "SSH Keys"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of SSH keys",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SshKey"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "summary": "Add SSH Key",
        "description": "Upload an SSH public key.",
        "operationId": "addSshKey",
        "tags": [
          "SSH Keys"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSshKeyRequest"
              },
              "example": {
                "name": "my-laptop",
                "publicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExample user@laptop"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "SSH key created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/SshKey"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "summary": "Delete SSH Key",
        "description": "Delete an SSH key by ID.",
        "operationId": "deleteSshKey",
        "tags": [
          "SSH Keys"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "SSH key ID"
          }
        ],
        "responses": {
          "200": {
            "description": "SSH key deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "example": "deleted"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/v1/api-keys": {
      "get": {
        "summary": "List API Keys",
        "description": "List the API keys of the authenticated user. Only the key prefix and metadata are returned. Keys are created and revoked from the GPUcloud console only (Settings, API keys section, signed-in session): an API key cannot create or delete keys.",
        "operationId": "listApiKeys",
        "tags": [
          "API Keys"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of API keys",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ApiKey"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "clxyz123456",
                      "name": "CI/CD Pipeline",
                      "prefix": "gpu_k_abc1",
                      "lastUsedAt": "2026-06-24T10:00:00.000Z",
                      "createdAt": "2026-06-01T12:00:00.000Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/servers/{id}/backups": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Server ID"
        }
      ],
      "get": {
        "summary": "List backups",
        "description": "Backup option: daily backup of the system disk (100 GB: operating system, software and configuration), kept 7 days. The work disk (high-capacity local storage) is not included: back up your important data elsewhere. The server is briefly interrupted during the backup, at the time you choose. 9.99 $/month. Returns the option (enabled, hourLocal 0-23 Eastern time, retention, price, billing) and the backups (id, kind, status, date, size).",
        "operationId": "listServerBackups",
        "tags": [
          "Backups"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Backup option and backups",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "put": {
        "summary": "Backup option",
        "description": "Turn the option on (hourly server: billed pro rata per billed hour; prepaid server: the rest of the paid period now from credits, then with each renewal) or off (confirmDeleteBackups: true is required when backups exist: they are deleted), or change the hour / retention.",
        "operationId": "setServerBackupPolicy",
        "tags": [
          "Backups"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "hourLocal": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 23
                  },
                  "retention": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 7
                  },
                  "confirmDeleteBackups": {
                    "type": "boolean"
                  },
                  "expectedChargeCad": {
                    "type": "number"
                  }
                }
              },
              "example": {
                "enabled": true,
                "hourLocal": 3,
                "retention": 7
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Option updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "summary": "Back up now",
        "description": "Starts a backup of the system disk now (option enabled, at most 2 manual backups kept). The server is briefly interrupted (a few minutes).",
        "operationId": "createServerBackup",
        "tags": [
          "Backups"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Backup started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/servers/{id}/backups/{backupId}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Server ID"
        },
        {
          "name": "backupId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Backup ID (from GET /servers/{id}/backups)"
        }
      ],
      "delete": {
        "summary": "Delete a backup",
        "description": "Deletes one backup (not while it is being created).",
        "operationId": "deleteServerBackup",
        "tags": [
          "Backups"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Backup deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/servers/{id}/backups/{backupId}/restore": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Server ID"
        },
        {
          "name": "backupId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Backup ID (from GET /servers/{id}/backups)"
        }
      ],
      "get": {
        "summary": "Restore price",
        "description": "Price of restoring this backup to a NEW server (hourly billing: first hour from credits).",
        "operationId": "quoteBackupRestore",
        "tags": [
          "Backups"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Restore price",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "summary": "Restore to a new server",
        "description": "Creates a NEW server (same GPU model and region) from the backup; the original server is not changed. Billed like any new hourly server (first hour from credits, budget limits apply).",
        "operationId": "restoreServerBackup",
        "tags": [
          "Backups"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "expectedHourlyRateCad": {
                    "type": "number"
                  }
                }
              },
              "example": {
                "name": "train-restored"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "New server created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Backup not ready / out of stock"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "REST API key (prefix gpu_) created in the GPUcloud console (Settings). Pass it as `Authorization: Bearer <your-api-key>`. Keys expire after 90 days; a read-only key may only call GET. Write requests (POST, PUT, DELETE) must also send `Origin: https://gpucloud.ca`."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      },
      "GpuPlan": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "gpu-l40-x2"
          },
          "name": {
            "type": "string",
            "example": "NVIDIA L40 × 2"
          },
          "gpu": {
            "type": "string",
            "example": "2x NVIDIA L40 (48 GB GDDR6)"
          },
          "gpuModel": {
            "type": "string",
            "example": "NVIDIA L40"
          },
          "gpuCount": {
            "type": "integer",
            "description": "GPUs of the server (1, 2, 4 or 8)",
            "example": 2
          },
          "spot": {
            "type": "boolean",
            "description": "Spot server: interruptible without notice, hourly billing only"
          },
          "hourlyOnly": {
            "type": "boolean",
            "description": "True when only hourly billing is offered (monthly and annual are refused with CYCLE_NOT_AVAILABLE)"
          },
          "specs": {
            "type": "object",
            "properties": {
              "vcores": {
                "type": "integer",
                "example": 60
              },
              "ram": {
                "type": "integer",
                "description": "RAM in GB",
                "example": 116
              },
              "storage": {
                "type": "integer",
                "description": "System disk in GB",
                "example": 100
              },
              "storageType": {
                "type": "string",
                "example": "NVMe"
              },
              "localStorage": {
                "type": "integer",
                "description": "Local (ephemeral) work disk in GB, 0 when none",
                "example": 1550
              }
            }
          },
          "pricing": {
            "type": "object",
            "nullable": true,
            "description": "Prices billed to the caller, per server (all its GPUs). null when priceOnRequest is true: the plan has no public price and is not sold online (contact us for a quote).",
            "properties": {
              "hourly": {
                "type": "number",
                "description": "On-demand hourly rate in CAD",
                "example": 2.68
              },
              "monthly": {
                "type": "number",
                "nullable": true,
                "description": "Monthly committed rate in CAD (null: hourly only)",
                "example": 1876.1
              },
              "annual": {
                "type": "number",
                "nullable": true,
                "description": "Annual committed monthly rate in CAD (null: hourly only)",
                "example": 1876.1
              },
              "currency": {
                "type": "string",
                "example": "CAD"
              }
            }
          },
          "priceOnRequest": {
            "type": "boolean",
            "description": "True when the plan is sold on request only (no public price, pricing is null, never purchasable online)"
          },
          "available": {
            "type": "boolean",
            "description": "Whether this server size is currently in stock"
          },
          "purchasable": {
            "type": "boolean",
            "description": "Whether this GPU plan can be purchased (may be false if plan is visible but not yet offered)"
          },
          "autoProvisioning": {
            "type": "boolean",
            "description": "Whether this GPU can be auto-deployed via API"
          },
          "eligibility": {
            "type": "string",
            "enum": [
              "deployable",
              "contact",
              "out_of_stock",
              "disabled"
            ],
            "description": "Plan deployment eligibility status"
          }
        }
      },
      "ServerSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "PROVISIONING",
              "ACTIVE",
              "STOPPED",
              "REBOOTING",
              "HIBERNATED",
              "ERROR",
              "DELETED"
            ]
          },
          "gpu": {
            "type": "string"
          },
          "specs": {
            "type": "object",
            "properties": {
              "vcores": {
                "type": "integer"
              },
              "ram": {
                "type": "integer"
              },
              "storage": {
                "type": "integer"
              }
            }
          },
          "ipv4": {
            "type": "string",
            "nullable": true
          },
          "region": {
            "type": "string"
          },
          "monthlyCost": {
            "type": "number"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ServerDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "gpu": {
            "type": "string"
          },
          "specs": {
            "type": "object",
            "properties": {
              "vcores": {
                "type": "integer"
              },
              "ram": {
                "type": "integer"
              },
              "storage": {
                "type": "integer"
              }
            }
          },
          "ipv4": {
            "type": "string",
            "nullable": true
          },
          "ipv6": {
            "type": "string",
            "nullable": true
          },
          "region": {
            "type": "string"
          },
          "monthlyCost": {
            "type": "number"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ServerCreated": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "example": "PROVISIONING"
          },
          "gpu": {
            "type": "string"
          }
        }
      },
      "CreateServerRequest": {
        "type": "object",
        "required": [
          "productId",
          "sshKeyId"
        ],
        "properties": {
          "productId": {
            "type": "string",
            "description": "GPU plan id (GET /v1/gpu), e.g. gpu-l40",
            "example": "gpu-l40"
          },
          "sshKeyId": {
            "type": "string",
            "description": "SSH key id (GET /settings/ssh-keys)"
          },
          "name": {
            "type": "string",
            "maxLength": 100,
            "description": "Optional server name"
          },
          "region": {
            "type": "string",
            "enum": [
              "canada-montreal"
            ],
            "default": "canada-montreal",
            "description": "Deployment region"
          }
        }
      },
      "ActionRequest": {
        "type": "object",
        "required": [
          "action"
        ],
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "start",
              "stop",
              "reboot",
              "hibernate",
              "hibernate-restore"
            ],
            "description": "The power action to execute"
          }
        }
      },
      "Metrics": {
        "type": "object",
        "properties": {
          "cpu": {
            "type": "object",
            "properties": {
              "timestamps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "values": {
                "type": "array",
                "items": {
                  "type": "number"
                }
              }
            }
          },
          "ram": {
            "type": "object",
            "properties": {
              "timestamps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "values": {
                "type": "array",
                "items": {
                  "type": "number"
                }
              }
            }
          },
          "network_in": {
            "type": "object",
            "properties": {
              "timestamps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "values": {
                "type": "array",
                "items": {
                  "type": "number"
                }
              }
            }
          },
          "network_out": {
            "type": "object",
            "properties": {
              "timestamps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "values": {
                "type": "array",
                "items": {
                  "type": "number"
                }
              }
            }
          }
        }
      },
      "FirewallRule": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "direction": {
            "type": "string",
            "enum": [
              "ingress",
              "egress"
            ]
          },
          "protocol": {
            "type": "string",
            "enum": [
              "tcp",
              "udp",
              "icmp"
            ]
          },
          "port": {
            "oneOf": [
              {
                "type": "integer"
              },
              {
                "type": "string"
              }
            ],
            "description": "Single port number or range (e.g. \"8000-9000\")"
          },
          "source": {
            "type": "string",
            "description": "CIDR notation (e.g. 0.0.0.0/0)"
          },
          "status": {
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          }
        }
      },
      "CreateFirewallRuleRequest": {
        "type": "object",
        "required": [
          "direction",
          "protocol"
        ],
        "properties": {
          "direction": {
            "type": "string",
            "enum": [
              "ingress",
              "egress"
            ]
          },
          "protocol": {
            "type": "string",
            "enum": [
              "tcp",
              "udp",
              "icmp"
            ]
          },
          "ethertype": {
            "type": "string",
            "enum": [
              "IPv4",
              "IPv6"
            ],
            "default": "IPv4"
          },
          "remoteIpPrefix": {
            "type": "string",
            "description": "Source CIDR (default: anywhere)",
            "example": "203.0.113.0/24"
          },
          "portRangeMin": {
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          },
          "portRangeMax": {
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          }
        }
      },
      "SshKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateSshKeyRequest": {
        "type": "object",
        "required": [
          "name",
          "publicKey"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100,
            "description": "A friendly name for the key"
          },
          "publicKey": {
            "type": "string",
            "description": "The SSH public key (e.g. ssh-ed25519 AAAA...)"
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string",
            "description": "Visible prefix of the key (e.g. gpu_k_abc1)"
          },
          "lastUsedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PublicAvailability": {
        "type": "object",
        "description": "Aggregated availability of the GPU catalog: per GPU model and machine size, only whether it can be deployed online right now.",
        "properties": {
          "region": {
            "type": "string",
            "example": "canada-montreal"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "models": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "slug": {
                  "type": "string",
                  "description": "Model page: https://gpucloud.ca/{fr|en}/gpu/{slug}",
                  "example": "h100"
                },
                "name": {
                  "type": "string",
                  "example": "NVIDIA H100 PCIe"
                },
                "sizes": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "Catalog product id (as in /v1/gpu and POST /servers).",
                        "example": "gpu-h100-x2"
                      },
                      "gpuCount": {
                        "type": "integer",
                        "example": 2
                      },
                      "spot": {
                        "type": "boolean",
                        "description": "Interruptible machine, hourly billing only."
                      },
                      "available": {
                        "type": "boolean",
                        "description": "Deployable online right now."
                      },
                      "priceOnRequest": {
                        "type": "boolean",
                        "description": "Sold on request only (never deployable online)."
                      }
                    },
                    "required": [
                      "id",
                      "gpuCount",
                      "spot",
                      "available",
                      "priceOnRequest"
                    ]
                  }
                }
              },
              "required": [
                "slug",
                "name",
                "sizes"
              ]
            }
          }
        },
        "required": [
          "region",
          "updatedAt",
          "models"
        ]
      },
      "AccountAction": {
        "type": "object",
        "description": "What to do to fix an account or payment problem, with the direct absolute link. Same object on every route and in the MCP tool errors (structuredContent.error.accountAction). The message is in French when Accept-Language asks for it, otherwise in English.",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "NO_API_KEY",
              "INVALID_API_KEY",
              "PAYMENT_REQUIRED",
              "BUDGET_CAP_REACHED"
            ],
            "description": "Stable machine code. NO_API_KEY and INVALID_API_KEY come with HTTP 401, PAYMENT_REQUIRED and BUDGET_CAP_REACHED with HTTP 402."
          },
          "message": {
            "type": "string",
            "description": "Clear sentence telling what to do, including the link."
          },
          "action": {
            "type": "object",
            "properties": {
              "label": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "label",
              "url"
            ]
          },
          "links": {
            "type": "object",
            "description": "Absolute links: account creation, sign in, API keys page, billing, add credits (opens the credit window), payment card, budget or cap setting, documentation.",
            "properties": {
              "signup": {
                "type": "string",
                "format": "uri"
              },
              "login": {
                "type": "string",
                "format": "uri"
              },
              "apiKeys": {
                "type": "string",
                "format": "uri"
              },
              "billing": {
                "type": "string",
                "format": "uri"
              },
              "addCredits": {
                "type": "string",
                "format": "uri"
              },
              "paymentMethod": {
                "type": "string",
                "format": "uri"
              },
              "budget": {
                "type": "string",
                "format": "uri"
              },
              "documentation": {
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "signup",
              "login",
              "apiKeys",
              "billing",
              "addCredits",
              "paymentMethod",
              "budget",
              "documentation"
            ]
          },
          "minimumCad": {
            "type": "number",
            "description": "PAYMENT_REQUIRED only, when known: credits (CAD) covering one hour of the GPU asked for, computed by the server from the same price as the deployment."
          },
          "minimumTopupCad": {
            "type": "number",
            "description": "Smallest credit purchase accepted (CAD), given with minimumCad."
          }
        },
        "required": [
          "code",
          "message",
          "action",
          "links"
        ]
      },
      "AccountActionError": {
        "type": "object",
        "description": "Error of an account or payment problem. Backward compatible: `error` keeps its previous string value (for example \"Unauthorized\" or \"INSUFFICIENT_CREDITS\"), `message` and the existing details stay; `accountAction` is added.",
        "properties": {
          "error": {
            "type": "string",
            "description": "Previous error string or code, unchanged (backward compatibility)."
          },
          "message": {
            "type": "string"
          },
          "requiredCredits": {
            "type": "number",
            "description": "INSUFFICIENT_CREDITS: credits (CAD) the action needs."
          },
          "currentBalance": {
            "type": "number"
          },
          "accountAction": {
            "$ref": "#/components/schemas/AccountAction"
          }
        },
        "required": [
          "error",
          "accountAction"
        ]
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "No API key (accountAction.code NO_API_KEY) or an invalid, expired, revoked or read only key on a write (INVALID_API_KEY). Provide a valid API key as `Authorization: Bearer <key>`; accountAction gives the links to create an account and a key.",
        "headers": {
          "WWW-Authenticate": {
            "schema": {
              "type": "string"
            },
            "description": "Bearer realm=\"gpucloud\" (error=\"invalid_token\" when a key was sent)."
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AccountActionError"
            },
            "examples": {
              "noKey": {
                "summary": "No key sent",
                "value": {
                  "error": "Unauthorized. Use Bearer API key.",
                  "message": "No API key was sent. Create a GPU Cloud account (https://gpucloud.ca/en/auth/register), then an API key in the console (https://gpucloud.ca/en/console/settings#api-keys), and send it in the header Authorization: Bearer gpu_...",
                  "accountAction": {
                    "code": "NO_API_KEY",
                    "message": "No API key was sent. Create a GPU Cloud account (https://gpucloud.ca/en/auth/register), then an API key in the console (https://gpucloud.ca/en/console/settings#api-keys), and send it in the header Authorization: Bearer gpu_...",
                    "action": {
                      "label": "Create an account",
                      "url": "https://gpucloud.ca/en/auth/register"
                    },
                    "links": {
                      "signup": "https://gpucloud.ca/en/auth/register",
                      "login": "https://gpucloud.ca/en/auth/login",
                      "apiKeys": "https://gpucloud.ca/en/console/settings#api-keys",
                      "billing": "https://gpucloud.ca/en/console/billing",
                      "addCredits": "https://gpucloud.ca/en/console/billing?addCredits=25",
                      "paymentMethod": "https://gpucloud.ca/en/console/billing#payment-method",
                      "budget": "https://gpucloud.ca/en/console/billing#budget-limit",
                      "documentation": "https://gpucloud.ca/en/developers#errors"
                    }
                  }
                }
              },
              "invalidKey": {
                "summary": "Invalid, expired or revoked key",
                "value": {
                  "error": "Unauthorized",
                  "message": "This API key is invalid, expired, revoked or lacks the required permission. Create a new API key in the console (https://gpucloud.ca/en/console/settings#api-keys) and send it in the header Authorization: Bearer gpu_... No account yet: https://gpucloud.ca/en/auth/register",
                  "accountAction": {
                    "code": "INVALID_API_KEY",
                    "message": "This API key is invalid, expired, revoked or lacks the required permission. Create a new API key in the console (https://gpucloud.ca/en/console/settings#api-keys) and send it in the header Authorization: Bearer gpu_... No account yet: https://gpucloud.ca/en/auth/register",
                    "action": {
                      "label": "Create an API key",
                      "url": "https://gpucloud.ca/en/console/settings#api-keys"
                    },
                    "links": {
                      "signup": "https://gpucloud.ca/en/auth/register",
                      "login": "https://gpucloud.ca/en/auth/login",
                      "apiKeys": "https://gpucloud.ca/en/console/settings#api-keys",
                      "billing": "https://gpucloud.ca/en/console/billing",
                      "addCredits": "https://gpucloud.ca/en/console/billing?addCredits=25",
                      "paymentMethod": "https://gpucloud.ca/en/console/billing#payment-method",
                      "budget": "https://gpucloud.ca/en/console/billing#budget-limit",
                      "documentation": "https://gpucloud.ca/en/developers#errors"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Server not found"
            }
          }
        }
      },
      "BadRequest": {
        "description": "Invalid request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Invalid input"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Rate limit exceeded",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Too many requests"
            }
          }
        }
      },
      "InternalError": {
        "description": "Internal server error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Internal server error"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "Payment required (accountAction.code PAYMENT_REQUIRED: not enough credit, no saved card or a declined card) or a budget cap reached (BUDGET_CAP_REACHED: account or server budget limit, nothing charged). Add your card and credits at accountAction.action.url (or raise the cap), then send the same request again.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AccountActionError"
            },
            "examples": {
              "insufficientCredits": {
                "summary": "Not enough credit to deploy",
                "value": {
                  "error": "INSUFFICIENT_CREDITS",
                  "message": "Payment required. You need a paid order or at least enough credits for 1 hour of usage.",
                  "requiredCredits": 1.34,
                  "currentBalance": 0,
                  "accountAction": {
                    "code": "PAYMENT_REQUIRED",
                    "message": "Payment required. Add your card and credits here, then run the same request again: you will get your GPU. https://gpucloud.ca/en/console/billing?addCredits=25 At least 1.34 CAD is needed to cover one hour of this GPU (smallest credit purchase: 25 CAD).",
                    "action": {
                      "label": "Add a card and credits",
                      "url": "https://gpucloud.ca/en/console/billing?addCredits=25"
                    },
                    "links": {
                      "signup": "https://gpucloud.ca/en/auth/register",
                      "login": "https://gpucloud.ca/en/auth/login",
                      "apiKeys": "https://gpucloud.ca/en/console/settings#api-keys",
                      "billing": "https://gpucloud.ca/en/console/billing",
                      "addCredits": "https://gpucloud.ca/en/console/billing?addCredits=25",
                      "paymentMethod": "https://gpucloud.ca/en/console/billing#payment-method",
                      "budget": "https://gpucloud.ca/en/console/billing#budget-limit",
                      "documentation": "https://gpucloud.ca/en/developers#errors"
                    },
                    "minimumCad": 1.34,
                    "minimumTopupCad": 25
                  }
                }
              },
              "budgetCap": {
                "summary": "Account budget limit reached",
                "value": {
                  "error": "BUDGET_LIMIT_REACHED",
                  "message": "The monthly budget limit of this account is reached.",
                  "scope": "account",
                  "accountAction": {
                    "code": "BUDGET_CAP_REACHED",
                    "message": "The budget limit of this account was reached: nothing was charged. The account owner can raise or remove this limit here, then run the same request again: https://gpucloud.ca/en/console/billing#budget-limit",
                    "action": {
                      "label": "Change the limit",
                      "url": "https://gpucloud.ca/en/console/billing#budget-limit"
                    },
                    "links": {
                      "signup": "https://gpucloud.ca/en/auth/register",
                      "login": "https://gpucloud.ca/en/auth/login",
                      "apiKeys": "https://gpucloud.ca/en/console/settings#api-keys",
                      "billing": "https://gpucloud.ca/en/console/billing",
                      "addCredits": "https://gpucloud.ca/en/console/billing?addCredits=25",
                      "paymentMethod": "https://gpucloud.ca/en/console/billing#payment-method",
                      "budget": "https://gpucloud.ca/en/console/billing#budget-limit",
                      "documentation": "https://gpucloud.ca/en/developers#errors"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
