{
  "openapi": "3.1.0",
  "info": {
    "title": "AI Hosting agent ordering",
    "version": "1.1.0",
    "description": "Bounded agent orders. Clients may separately authorize a concrete order for card payment at its annual price and complete Stripe card setup. Payment endpoint never accepts card data or client consent from the agent. Check catalog availability flags. SCA requires a client handoff. No MCP connector."
  },
  "servers": [
    {
      "url": "https://ai-hosting.cz/api/agent/v1"
    }
  ],
  "security": [
    {
      "AgentGrant": []
    }
  ],
  "components": {
    "securitySchemes": {
      "AgentGrant": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "aho_ + 64 hex characters"
      }
    }
  },
  "paths": {
    "/catalog": {
      "get": {
        "operationId": "hostingCatalog",
        "summary": "Current annual prices, limits and live-payment availability",
        "responses": {
          "200": {
            "description": "Result. Amounts are CZK minor units. Errors: 401 invalid/expired/revoked credential; 403 missing deployment permission; 404 foreign or unknown order; 409 price, budget, idempotency or state conflict; 422 validation; 429 rate limit."
          },
          "401": {
            "description": "Invalid credential"
          },
          "403": {
            "description": "Permission denied"
          },
          "404": {
            "description": "Not found"
          },
          "409": {
            "description": "Conflict"
          },
          "422": {
            "description": "Invalid request"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        },
        "security": []
      }
    },
    "/orders": {
      "post": {
        "operationId": "prepareHostingOrder",
        "summary": "Prepare a draft. Does not charge a card or activate hosting.",
        "responses": {
          "201": {
            "description": "Result. Amounts are CZK minor units. Errors: 401 invalid/expired/revoked credential; 403 missing deployment permission; 404 foreign or unknown order; 409 price, budget, idempotency or state conflict; 422 validation; 429 rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "approval_url": {
                      "type": "string"
                    },
                    "annual_minor": {
                      "type": "integer"
                    },
                    "deployment_ready": {
                      "type": "boolean"
                    },
                    "live_payments_enabled": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid credential"
          },
          "403": {
            "description": "Permission denied"
          },
          "404": {
            "description": "Not found"
          },
          "409": {
            "description": "Conflict"
          },
          "422": {
            "description": "Invalid request"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 16,
              "maxLength": 80,
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subdomain",
                  "capacity_gb",
                  "expected_annual_minor"
                ],
                "properties": {
                  "subdomain": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 40,
                    "pattern": "^[a-z0-9](?:[a-z0-9-]{1,38}[a-z0-9])$"
                  },
                  "capacity_gb": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10
                  },
                  "expected_annual_minor": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "36500 for 1 GB, plus 30000 per additional GB. Verify catalog."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/orders/{order}": {
      "parameters": [
        {
          "name": "order",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "operationId": "hostingOrderStatus",
        "summary": "Read only orders created by this grant.",
        "responses": {
          "200": {
            "description": "Result. Amounts are CZK minor units. Errors: 401 invalid/expired/revoked credential; 403 missing deployment permission; 404 foreign or unknown order; 409 price, budget, idempotency or state conflict; 422 validation; 429 rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "approval_url": {
                      "type": "string"
                    },
                    "annual_minor": {
                      "type": "integer"
                    },
                    "deployment_ready": {
                      "type": "boolean"
                    },
                    "live_payments_enabled": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid credential"
          },
          "403": {
            "description": "Permission denied"
          },
          "404": {
            "description": "Not found"
          },
          "409": {
            "description": "Conflict"
          },
          "422": {
            "description": "Invalid request"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        }
      }
    },
    "/orders/{order}/deployment-key": {
      "parameters": [
        {
          "name": "order",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "operationId": "rotateDeploymentKey",
        "summary": "Requires explicit deployment delegation and active hosting. Returns secret once; retries revoke previous key.",
        "responses": {
          "200": {
            "description": "Result. Amounts are CZK minor units. Errors: 401 invalid/expired/revoked credential; 403 missing deployment permission; 404 foreign or unknown order; 409 price, budget, idempotency or state conflict; 422 validation; 429 rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "token": {
                      "type": "string",
                      "description": "Secret for existing /api/v1 API. Never put in chat, frontend or repository."
                    },
                    "api_base": {
                      "type": "string"
                    },
                    "expires_at": {
                      "type": "string"
                    },
                    "retry_behavior": {
                      "const": "rotates_previous_key"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid credential"
          },
          "403": {
            "description": "Permission denied"
          },
          "404": {
            "description": "Not found"
          },
          "409": {
            "description": "Conflict"
          },
          "422": {
            "description": "Invalid request"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        }
      }
    },
    "/orders/{order}/pay": {
      "parameters": [
        {
          "name": "order",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "operationId": "payAuthorizedHostingOrder",
        "summary": "Initiate or retrieve ONE subscription authorized separately by the owner. Requires saved card setup; safe to repeat for the same order. Never create another order after ambiguous errors.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ],
                    "default": "live",
                    "description": "test only for operator allowlisted accounts"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "payment_status: processing, requires_customer_action, paid_pending_activation, failed. customer_action_url directs owner to authentication. site_active remains false until verified payment and provisioning."
          },
          "401": {
            "description": "Revoked or expired grant"
          },
          "403": {
            "description": "Mode forbidden"
          },
          "404": {
            "description": "Unknown or foreign order"
          },
          "409": {
            "description": "Missing/expired/revoked mandate, changed price, unfinished card setup, or unresolved earlier attempt"
          },
          "503": {
            "description": "Payments disabled or uncertain Stripe response. Retry SAME order."
          }
        }
      }
    }
  }
}
