{
  "openapi": "3.1.1",
  "info": {
    "title": "CGS Games API",
    "version": "1.0.0",
    "description": "Discover community Card Game Simulator games. Public reads require no authentication. Publishing and deletion use Firebase ID tokens and a user profile with a username. API errors retain the legacy error string and add code, message, and hint. GET routes also support HEAD; OPTIONS lists allowed methods. Unknown API paths return JSON 404; unsupported methods return JSON 405 with Allow. Select major version 1 with API-Version: 1 (also the default). Unsupported versions return 400. Breaking changes require a new major version; at least 90 days notice precedes retirement using Deprecation (RFC 9745), Sunset (RFC 8594), and a migration Link. Version 1 has no scheduled retirement. See /developers#versioning.",
    "contact": {
      "name": "CGS Games support",
      "url": "https://cgs.games/contact",
      "email": "david@finoldigital.com"
    }
  },
  "servers": [
    {
      "url": "https://cgs.games"
    }
  ],
  "externalDocs": {
    "description": "CGS Games developer portal: quickstart, authentication, sandbox and versioning",
    "url": "https://cgs.games/developers"
  },
  "security": [],
  "paths": {
    "/api/games": {
      "get": {
        "operationId": "listGames",
        "summary": "List the newest games",
        "responses": {
          "200": {
            "description": "Up to 100 games ordered by uploadedAt descending; no pagination or query filters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "maxItems": 100,
                  "items": {
                    "$ref": "#/components/schemas/Game"
                  }
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or unsupported API version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "500": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "List the newest games. See https://cgs.games/developers for integration guidance."
      },
      "post": {
        "operationId": "publishGame",
        "summary": "Publish a game from its auto-update URL",
        "security": [
          {
            "firebaseIdToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["autoUpdateUrl"],
                "properties": {
                  "autoUpdateUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Public HTTPS URL on port 443 without embedded credentials, serving a CGS JSON game specification including name and optional bannerImageUrl, cardBackImageUrl, and copyright. Private or reserved destinations are rejected, including after redirects. Up to five redirects and a 16 MiB response body are accepted.",
                    "pattern": "^https://"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Game published successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublishedGame"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "401": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "404": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "500": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "502": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Publish a game from its auto-update URL. See https://cgs.games/developers for integration guidance."
      },
      "head": {
        "operationId": "listGamesHeaders",
        "summary": "Read headers for list the newest games",
        "description": "Same authentication, query parameters and processing as GET, without a response body.",
        "responses": {
          "200": {
            "description": "Up to 100 games ordered by uploadedAt descending; no pagination or query filters.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or unsupported API version; no response body.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "500": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "optionsapigames",
        "summary": "Discover allowed methods and CORS preflight permissions",
        "security": [],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "description": "Origin of the requesting browser."
          },
          {
            "name": "Access-Control-Request-Method",
            "in": "header",
            "schema": {
              "type": "string",
              "enum": ["GET", "HEAD", "POST"]
            },
            "description": "Method requested by a browser preflight."
          },
          {
            "name": "Access-Control-Request-Headers",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "example": "Content-Type, Authorization",
            "description": "Access-Control-Request-Headers request value."
          }
        ],
        "responses": {
          "204": {
            "description": "Preflight accepted with no response body.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, POST, OPTIONS"
              },
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string",
                  "const": "*"
                }
              },
              "Access-Control-Allow-Methods": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, POST, OPTIONS"
              },
              "Access-Control-Allow-Headers": {
                "schema": {
                  "type": "string"
                },
                "example": "Content-Type, Authorization, API-Version"
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Discover allowed methods and CORS preflight permissions. See https://cgs.games/developers for integration guidance."
      },
      "parameters": [
        {
          "name": "API-Version",
          "in": "header",
          "required": false,
          "description": "Major API version. Omit for version 1; any other value returns 400 UNSUPPORTED_API_VERSION. See /developers#versioning.",
          "schema": {
            "type": "string",
            "enum": ["1"],
            "default": "1"
          }
        }
      ]
    },
    "/api/browse": {
      "get": {
        "operationId": "browseGames",
        "summary": "Legacy alias for the game catalog",
        "responses": {
          "200": {
            "description": "Up to 100 games ordered by uploadedAt descending; no pagination or query filters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "maxItems": 100,
                  "items": {
                    "$ref": "#/components/schemas/Game"
                  }
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or unsupported API version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "500": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Legacy alias for the game catalog. See https://cgs.games/developers for integration guidance."
      },
      "head": {
        "operationId": "browseGamesHeaders",
        "summary": "Read headers for legacy alias for the game catalog",
        "description": "Same authentication, query parameters and processing as GET, without a response body.",
        "responses": {
          "200": {
            "description": "Up to 100 games ordered by uploadedAt descending; no pagination or query filters.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or unsupported API version; no response body.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "500": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "optionsapibrowse",
        "summary": "Discover allowed methods and CORS preflight permissions",
        "security": [],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "description": "Origin of the requesting browser."
          },
          {
            "name": "Access-Control-Request-Method",
            "in": "header",
            "schema": {
              "type": "string",
              "enum": ["GET", "HEAD"]
            },
            "description": "Method requested by a browser preflight."
          },
          {
            "name": "Access-Control-Request-Headers",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "example": "Content-Type, Authorization",
            "description": "Access-Control-Request-Headers request value."
          }
        ],
        "responses": {
          "204": {
            "description": "Preflight accepted with no response body.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, OPTIONS"
              },
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string",
                  "const": "*"
                }
              },
              "Access-Control-Allow-Methods": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, OPTIONS"
              },
              "Access-Control-Allow-Headers": {
                "schema": {
                  "type": "string"
                },
                "example": "Content-Type, Authorization, API-Version"
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Discover allowed methods and CORS preflight permissions. See https://cgs.games/developers for integration guidance."
      },
      "parameters": [
        {
          "name": "API-Version",
          "in": "header",
          "required": false,
          "description": "Major API version. Omit for version 1; any other value returns 400 UNSUPPORTED_API_VERSION. See /developers#versioning.",
          "schema": {
            "type": "string",
            "enum": ["1"],
            "default": "1"
          }
        }
      ]
    },
    "/api/games/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Firestore game document ID from the catalog, not a game slug.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "API-Version",
          "in": "header",
          "required": false,
          "description": "Major API version. Omit for version 1; any other value returns 400 UNSUPPORTED_API_VERSION. See /developers#versioning.",
          "schema": {
            "type": "string",
            "enum": ["1"],
            "default": "1"
          }
        }
      ],
      "delete": {
        "operationId": "deleteGame",
        "summary": "Delete a game owned by the authenticated creator",
        "security": [
          {
            "firebaseIdToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Game deleted. Existing success response is plain text.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "example": "Game deleted successfully"
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "401": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "403": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "404": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "500": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Delete a game owned by the authenticated creator. See https://cgs.games/developers for integration guidance."
      },
      "options": {
        "operationId": "optionsapigamesid",
        "summary": "Discover allowed methods and CORS preflight permissions",
        "security": [],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "description": "Origin of the requesting browser."
          },
          {
            "name": "Access-Control-Request-Method",
            "in": "header",
            "schema": {
              "type": "string",
              "enum": ["DELETE"]
            },
            "description": "Method requested by a browser preflight."
          },
          {
            "name": "Access-Control-Request-Headers",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "example": "Content-Type, Authorization",
            "description": "Access-Control-Request-Headers request value."
          }
        ],
        "responses": {
          "204": {
            "description": "Preflight accepted with no response body.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string"
                },
                "example": "DELETE, OPTIONS"
              },
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string",
                  "const": "*"
                }
              },
              "Access-Control-Allow-Methods": {
                "schema": {
                  "type": "string"
                },
                "example": "DELETE, OPTIONS"
              },
              "Access-Control-Allow-Headers": {
                "schema": {
                  "type": "string"
                },
                "example": "Content-Type, Authorization, API-Version"
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Discover allowed methods and CORS preflight permissions. See https://cgs.games/developers for integration guidance."
      }
    },
    "/api/games/upload": {
      "post": {
        "operationId": "uploadGame",
        "summary": "Publish a .cgs.zip archive (maximum 100 MiB)",
        "description": "Send a multipart file directly, or first upload the archive to Firebase Storage using an authenticated client and then submit its staged path. A staged archive is cleaned up after processing is attempted. Archives need a valid cgs.json and supported game assets.",
        "security": [
          {
            "firebaseIdToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["file"],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": ".cgs.zip archive, at most 104857600 bytes."
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["stagedPath", "originalFilename"],
                "properties": {
                  "stagedPath": {
                    "type": "string",
                    "pattern": "^staged-uploads/[^/]+/[A-Za-z0-9_-]+\\.cgs\\.zip$",
                    "description": "staged-uploads/{authenticated Firebase uid}/{unique-id}.cgs.zip"
                  },
                  "originalFilename": {
                    "type": "string",
                    "pattern": "\\.cgs\\.zip$"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Game published successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublishedGame"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "401": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "404": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "409": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "413": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "500": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "optionsapigamesupload",
        "summary": "Discover allowed methods and CORS preflight permissions",
        "security": [],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "description": "Origin of the requesting browser."
          },
          {
            "name": "Access-Control-Request-Method",
            "in": "header",
            "schema": {
              "type": "string",
              "enum": ["POST"]
            },
            "description": "Method requested by a browser preflight."
          },
          {
            "name": "Access-Control-Request-Headers",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "example": "Content-Type, Authorization",
            "description": "Access-Control-Request-Headers request value."
          }
        ],
        "responses": {
          "204": {
            "description": "Preflight accepted with no response body.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string"
                },
                "example": "POST, OPTIONS"
              },
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string",
                  "const": "*"
                }
              },
              "Access-Control-Allow-Methods": {
                "schema": {
                  "type": "string"
                },
                "example": "POST, OPTIONS"
              },
              "Access-Control-Allow-Headers": {
                "schema": {
                  "type": "string"
                },
                "example": "Content-Type, Authorization, API-Version"
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Discover allowed methods and CORS preflight permissions. See https://cgs.games/developers for integration guidance."
      },
      "parameters": [
        {
          "name": "API-Version",
          "in": "header",
          "required": false,
          "description": "Major API version. Omit for version 1; any other value returns 400 UNSUPPORTED_API_VERSION. See /developers#versioning.",
          "schema": {
            "type": "string",
            "enum": ["1"],
            "default": "1"
          }
        }
      ]
    },
    "/api/gatcg_spoilers": {
      "get": {
        "operationId": "getGrandArchiveSpoilers",
        "summary": "Read cached Grand Archive spoiler card data",
        "description": "Normally reads the assembled cache. Rate limited to 10 requests per minute per client IP per running instance. Operators may use warm=1 with the separate GATCG_WARM_TOKEN Bearer secret in production; a Firebase ID token does not grant this access. Unauthorized nocache=1 is ignored. warm runs can take up to 240 seconds and are not rate limited.",
        "parameters": [
          {
            "name": "warm",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["1"]
            },
            "description": "Operator-only cache rebuild; requires the warmToken security scheme in production."
          },
          {
            "name": "refresh",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["1"]
            },
            "description": "Re-run OCR from scratch. Only applies with warm=1."
          },
          {
            "name": "nocache",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["1"]
            },
            "description": "Operator-only assembled cache bypass, preserving the OCR cache. Ignored without operator authorization."
          }
        ],
        "security": [
          {},
          {
            "warmToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Spoiler cards in a data array. Pending OCR may leave effect_raw empty.",
            "headers": {
              "X-Cache": {
                "schema": {
                  "type": "string",
                  "enum": ["hit", "miss", "warm", "stale"]
                },
                "description": "Cache result."
              },
              "X-Ocr-Pending": {
                "schema": {
                  "type": "integer",
                  "minimum": 0
                },
                "description": "Cards awaiting OCR."
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              },
              "RateLimit-Policy": {
                "description": "IETF draft-ietf-httpapi-ratelimit-headers-11 quota policy. Present for normal rate-limited reads, not authorized warm runs.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";q=10;w=60"
              },
              "RateLimit": {
                "description": "IETF draft structured field: r is remaining requests; t is seconds until reset. Per IP per running instance. Normal rate-limited reads only.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";r=9;t=60"
              },
              "X-RateLimit-Limit": {
                "description": "Legacy request quota.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Legacy remaining requests.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Legacy absolute reset time (ISO 8601), unlike the relative t in RateLimit.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SpoilerCard"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or unsupported API version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "401": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "429": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Wait at least this many seconds before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              },
              "RateLimit-Policy": {
                "description": "IETF draft-ietf-httpapi-ratelimit-headers-11 quota policy. Present for normal rate-limited reads, not authorized warm runs.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";q=10;w=60"
              },
              "RateLimit": {
                "description": "IETF draft structured field: r is remaining requests; t is seconds until reset. Per IP per running instance. Normal rate-limited reads only.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";r=9;t=60"
              },
              "X-RateLimit-Limit": {
                "description": "Legacy request quota.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Legacy remaining requests.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Legacy absolute reset time (ISO 8601), unlike the relative t in RateLimit.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "502": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              },
              "RateLimit-Policy": {
                "description": "IETF draft-ietf-httpapi-ratelimit-headers-11 quota policy. Present for normal rate-limited reads, not authorized warm runs.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";q=10;w=60"
              },
              "RateLimit": {
                "description": "IETF draft structured field: r is remaining requests; t is seconds until reset. Per IP per running instance. Normal rate-limited reads only.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";r=9;t=60"
              },
              "X-RateLimit-Limit": {
                "description": "Legacy request quota.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Legacy remaining requests.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Legacy absolute reset time (ISO 8601), unlike the relative t in RateLimit.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        }
      },
      "head": {
        "operationId": "getGrandArchiveSpoilersHeaders",
        "summary": "Read headers for read cached grand archive spoiler card data",
        "description": "Same authentication, query parameters and processing as GET, without a response body.",
        "security": [
          {},
          {
            "warmToken": []
          }
        ],
        "parameters": [
          {
            "name": "warm",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["1"]
            },
            "description": "Operator-only cache rebuild; requires the warmToken security scheme in production."
          },
          {
            "name": "refresh",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["1"]
            },
            "description": "Re-run OCR from scratch. Only applies with warm=1."
          },
          {
            "name": "nocache",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["1"]
            },
            "description": "Operator-only assembled cache bypass, preserving the OCR cache. Ignored without operator authorization."
          }
        ],
        "responses": {
          "200": {
            "description": "Spoiler cards in a data array. Pending OCR may leave effect_raw empty.",
            "headers": {
              "X-Cache": {
                "schema": {
                  "type": "string",
                  "enum": ["hit", "miss", "warm", "stale"]
                },
                "description": "Cache result."
              },
              "X-Ocr-Pending": {
                "schema": {
                  "type": "integer",
                  "minimum": 0
                },
                "description": "Cards awaiting OCR."
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              },
              "RateLimit-Policy": {
                "description": "IETF draft-ietf-httpapi-ratelimit-headers-11 quota policy. Present for normal rate-limited reads, not authorized warm runs.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";q=10;w=60"
              },
              "RateLimit": {
                "description": "IETF draft structured field: r is remaining requests; t is seconds until reset. Per IP per running instance. Normal rate-limited reads only.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";r=9;t=60"
              },
              "X-RateLimit-Limit": {
                "description": "Legacy request quota.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Legacy remaining requests.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Legacy absolute reset time (ISO 8601), unlike the relative t in RateLimit.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or unsupported API version; no response body.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "401": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "429": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "Retry-After": {
                "description": "Wait at least this many seconds before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              },
              "RateLimit-Policy": {
                "description": "IETF draft-ietf-httpapi-ratelimit-headers-11 quota policy. Present for normal rate-limited reads, not authorized warm runs.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";q=10;w=60"
              },
              "RateLimit": {
                "description": "IETF draft structured field: r is remaining requests; t is seconds until reset. Per IP per running instance. Normal rate-limited reads only.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";r=9;t=60"
              },
              "X-RateLimit-Limit": {
                "description": "Legacy request quota.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Legacy remaining requests.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Legacy absolute reset time (ISO 8601), unlike the relative t in RateLimit.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "502": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              },
              "RateLimit-Policy": {
                "description": "IETF draft-ietf-httpapi-ratelimit-headers-11 quota policy. Present for normal rate-limited reads, not authorized warm runs.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";q=10;w=60"
              },
              "RateLimit": {
                "description": "IETF draft structured field: r is remaining requests; t is seconds until reset. Per IP per running instance. Normal rate-limited reads only.",
                "schema": {
                  "type": "string"
                },
                "example": "\"spoilers\";r=9;t=60"
              },
              "X-RateLimit-Limit": {
                "description": "Legacy request quota.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Legacy remaining requests.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Legacy absolute reset time (ISO 8601), unlike the relative t in RateLimit.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "optionsapigatcgspoilers",
        "summary": "Discover allowed methods and CORS preflight permissions",
        "security": [],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "description": "Origin of the requesting browser."
          },
          {
            "name": "Access-Control-Request-Method",
            "in": "header",
            "schema": {
              "type": "string",
              "enum": ["GET", "HEAD"]
            },
            "description": "Method requested by a browser preflight."
          },
          {
            "name": "Access-Control-Request-Headers",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "example": "Content-Type, Authorization",
            "description": "Access-Control-Request-Headers request value."
          }
        ],
        "responses": {
          "204": {
            "description": "Preflight accepted with no response body.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, OPTIONS"
              },
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string",
                  "const": "*"
                }
              },
              "Access-Control-Allow-Methods": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, OPTIONS"
              },
              "Access-Control-Allow-Headers": {
                "schema": {
                  "type": "string"
                },
                "example": "Content-Type, Authorization, API-Version"
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Discover allowed methods and CORS preflight permissions. See https://cgs.games/developers for integration guidance."
      },
      "parameters": [
        {
          "name": "API-Version",
          "in": "header",
          "required": false,
          "description": "Major API version. Omit for version 1; any other value returns 400 UNSUPPORTED_API_VERSION. See /developers#versioning.",
          "schema": {
            "type": "string",
            "enum": ["1"],
            "default": "1"
          }
        }
      ]
    },
    "/api/proxy/{url}": {
      "parameters": [
        {
          "name": "url",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Upstream host and path without a scheme, for example example.com/assets/game.json. This catch-all path can contain slashes; requires public HTTPS on port 443. Private IPs, embedded credentials, and unsafe redirects are rejected. GET forwards query parameters. Responses are limited to 100 MiB with a 30-second deadline; POST bodies to 16 MiB. Responses stream as bytes arrive. A limit or connection failure after headers aborts the stream; discard partial content. Active content is sandboxed and upstream cookies are never forwarded."
        },
        {
          "name": "API-Version",
          "in": "header",
          "required": false,
          "description": "Major API version. Omit for version 1; any other value returns 400 UNSUPPORTED_API_VERSION. See /developers#versioning.",
          "schema": {
            "type": "string",
            "enum": ["1"],
            "default": "1"
          }
        }
      ],
      "get": {
        "operationId": "proxyGet",
        "summary": "Fetch an upstream HTTPS resource",
        "responses": {
          "200": {
            "description": "Upstream body and Content-Type; may be JSON, an image, or other content.",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "502": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Fetch an upstream HTTPS resource. See https://cgs.games/developers for integration guidance. Upstream content is arbitrary, not a typed CGS function result; use catalog operations for structured game data."
      },
      "post": {
        "operationId": "proxyPost",
        "summary": "Forward a JSON body to an upstream HTTPS resource",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JsonValue"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful upstream response, including its headers and body.",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "Opaque upstream response bytes; inspect Content-Type before decoding."
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "502": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Forward a JSON body to an upstream HTTPS resource. See https://cgs.games/developers for integration guidance. Upstream content is arbitrary, not a typed CGS function result; use catalog operations for structured game data."
      },
      "head": {
        "operationId": "proxyGetHeaders",
        "summary": "Read headers for fetch an upstream https resource",
        "description": "Same authentication, query parameters and processing as GET, without a response body. Upstream content is arbitrary, not a typed CGS function result; use catalog operations for structured game data.",
        "responses": {
          "200": {
            "description": "Upstream body and Content-Type; may be JSON, an image, or other content.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "502": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "optionsapiproxyurl",
        "summary": "Discover allowed methods and CORS preflight permissions",
        "security": [],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "description": "Origin of the requesting browser."
          },
          {
            "name": "Access-Control-Request-Method",
            "in": "header",
            "schema": {
              "type": "string",
              "enum": ["GET", "HEAD", "POST"]
            },
            "description": "Method requested by a browser preflight."
          },
          {
            "name": "Access-Control-Request-Headers",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "example": "Content-Type, Authorization",
            "description": "Access-Control-Request-Headers request value."
          }
        ],
        "responses": {
          "204": {
            "description": "Preflight accepted with no response body.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, POST, OPTIONS"
              },
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string",
                  "const": "*"
                }
              },
              "Access-Control-Allow-Methods": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, POST, OPTIONS"
              },
              "Access-Control-Allow-Headers": {
                "schema": {
                  "type": "string"
                },
                "example": "Content-Type, Authorization, API-Version"
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Discover allowed methods and CORS preflight permissions. See https://cgs.games/developers for integration guidance. Upstream content is arbitrary, not a typed CGS function result; use catalog operations for structured game data."
      }
    },
    "/api/sandbox/games": {
      "get": {
        "operationId": "listSandboxGames",
        "summary": "Read a deterministic sandbox catalog",
        "responses": {
          "200": {
            "description": "A fixed example catalog matching the production Game schema.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "maxItems": 100,
                  "items": {
                    "$ref": "#/components/schemas/Game"
                  }
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or unsupported API version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "500": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Read-only Game fixtures, with no authentication, database access, or production mutations. Example URLs and creators do not refer to playable games. No sandbox writes are supported."
      },
      "head": {
        "operationId": "listSandboxGamesHeaders",
        "summary": "Read sandbox catalog headers",
        "description": "Same authentication, query parameters and processing as GET, without a response body.",
        "responses": {
          "200": {
            "description": "Headers for the fixed example catalog; no response body.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or unsupported API version; no response body.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "405": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "Allow": {
                "description": "Allowed HTTP methods.",
                "schema": {
                  "type": "string"
                }
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "500": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "default": {
            "description": "Structured error. See code, message, and hint for recovery.",
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "optionsSandboxGames",
        "summary": "Discover allowed methods and CORS preflight permissions",
        "security": [],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "description": "Origin of the requesting browser."
          },
          {
            "name": "Access-Control-Request-Method",
            "in": "header",
            "schema": {
              "type": "string",
              "enum": ["GET", "HEAD"]
            },
            "description": "Method requested by a browser preflight."
          },
          {
            "name": "Access-Control-Request-Headers",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "example": "Content-Type, Authorization",
            "description": "Access-Control-Request-Headers request value."
          }
        ],
        "responses": {
          "204": {
            "description": "Preflight accepted with no response body.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, OPTIONS"
              },
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string",
                  "const": "*"
                }
              },
              "Access-Control-Allow-Methods": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, OPTIONS"
              },
              "Access-Control-Allow-Headers": {
                "schema": {
                  "type": "string"
                },
                "example": "Content-Type, Authorization, API-Version"
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Discover allowed methods and CORS preflight permissions. See https://cgs.games/developers for integration guidance."
      },
      "parameters": [
        {
          "name": "API-Version",
          "in": "header",
          "required": false,
          "description": "Major API version. Omit for version 1; any other value returns 400 UNSUPPORTED_API_VERSION. See /developers#versioning.",
          "schema": {
            "type": "string",
            "enum": ["1"],
            "default": "1"
          }
        }
      ]
    },
    "/api/cli/session": {
      "parameters": [
        {
          "name": "API-Version",
          "in": "header",
          "required": false,
          "description": "Major API version. Omit for version 1; any other value returns 400 UNSUPPORTED_API_VERSION. See /developers#versioning.",
          "schema": {
            "type": "string",
            "enum": ["1"],
            "default": "1"
          }
        }
      ],
      "post": {
        "operationId": "verifyCliSession",
        "summary": "Verify the current CLI sign-in",
        "description": "Verifies a Firebase ID token including revocation and returns short-lived session metadata without issuing tokens or changing permissions. Responses are not cached. A creator username is required for publishing, but not for checking the session.",
        "security": [
          {
            "firebaseIdToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Verified session metadata; never includes a token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CliSession"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or unsupported API version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "401": {
            "description": "Invalid, expired or revoked Firebase ID token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          },
          "503": {
            "description": "Session information is temporarily unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "cliSessionOptions",
        "summary": "Discover allowed methods and CORS preflight permissions",
        "security": [],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "description": "Origin of the requesting browser."
          },
          {
            "name": "Access-Control-Request-Method",
            "in": "header",
            "schema": {
              "type": "string",
              "enum": ["POST"]
            },
            "description": "Method requested by a browser preflight."
          },
          {
            "name": "Access-Control-Request-Headers",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "example": "Content-Type, Authorization",
            "description": "Access-Control-Request-Headers request value."
          }
        ],
        "responses": {
          "204": {
            "description": "Preflight accepted with no response body.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string"
                },
                "example": "POST, OPTIONS"
              },
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string",
                  "const": "*"
                }
              },
              "Access-Control-Allow-Methods": {
                "schema": {
                  "type": "string"
                },
                "example": "POST, OPTIONS"
              },
              "Access-Control-Allow-Headers": {
                "schema": {
                  "type": "string"
                },
                "example": "Content-Type, Authorization, API-Version"
              },
              "API-Version": {
                "description": "Supported major API version.",
                "schema": {
                  "type": "string",
                  "enum": ["1"]
                }
              }
            }
          }
        },
        "description": "Returns POST and OPTIONS with CORS preflight headers for CLI session verification."
      }
    }
  },
  "components": {
    "securitySchemes": {
      "firebaseIdToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Firebase Auth ID token from the signed-in user. Publishing and deletion require a creator username; session verification does not."
      },
      "warmToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Operator GATCG_WARM_TOKEN secret. Only for spoiler cache maintenance; never a Firebase ID token."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": ["error", "code", "message", "hint"],
        "properties": {
          "error": {
            "type": "string",
            "description": "Legacy error message retained for existing clients."
          },
          "code": {
            "type": "string",
            "example": "NOT_FOUND"
          },
          "message": {
            "type": "string"
          },
          "hint": {
            "type": "string"
          }
        }
      },
      "PublishedGame": {
        "type": "object",
        "required": ["success", "slug"],
        "properties": {
          "success": {
            "const": true,
            "type": "boolean"
          },
          "slug": {
            "type": "string"
          }
        }
      },
      "Game": {
        "type": "object",
        "required": [
          "id",
          "username",
          "slug",
          "name",
          "bannerImageUrl",
          "autoUpdateUrl",
          "uploadedAt"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "username": {
            "type": "string"
          },
          "slug": {
            "type": "string",
            "description": "URL slug. Public game pages are /{username}/{slug}."
          },
          "name": {
            "type": "string"
          },
          "bannerImageUrl": {
            "type": "string",
            "description": "HTTPS banner URL or site-relative fallback image path."
          },
          "autoUpdateUrl": {
            "type": "string",
            "format": "uri"
          },
          "copyright": {
            "type": "string",
            "description": "Copyright attribution, when present. Some legacy listings omit this field; do not infer ownership from its absence."
          },
          "uploadedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SpoilerCard": {
        "type": "object",
        "required": [
          "uuid",
          "name",
          "card_image_url",
          "back_card_name",
          "back_card_image_url",
          "types",
          "element",
          "effect_raw"
        ],
        "properties": {
          "uuid": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "card_image_url": {
            "type": "string"
          },
          "back_card_name": {
            "type": "string"
          },
          "back_card_image_url": {
            "type": "string"
          },
          "element": {
            "type": "string"
          },
          "effect_raw": {
            "type": "string"
          },
          "types": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "JsonValue": {
        "description": "An arbitrary JSON value forwarded unchanged to the upstream service. No CGS domain schema is implied.",
        "anyOf": [
          {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/JsonValue"
            }
          },
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JsonValue"
            }
          },
          {
            "type": "string"
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          }
        ]
      },
      "CliSession": {
        "type": "object",
        "additionalProperties": false,
        "required": ["uid", "username", "expiresAt", "storageBucket"],
        "properties": {
          "uid": {
            "type": "string"
          },
          "username": {
            "type": ["string", "null"],
            "description": "Null until a creator username is chosen."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "storageBucket": {
            "type": "string",
            "description": "Firebase Storage bucket used for owned staged uploads."
          }
        }
      }
    }
  }
}
