{
  "openapi": "3.1.0",
  "info": {
    "title": "OcmodStudio Software Publishing API",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://apps.opxoc.com"
    }
  ],
  "components": {
    "securitySchemes": {
      "softwareToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "One token per product. Provisioned by administrator; never included in website or application installers."
      }
    }
  },
  "paths": {
    "/api/v1/products/{productId}": {
      "parameters": [
        {
          "name": "productId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
          }
        }
      ],
      "get": {
        "summary": "Read product and ETag revision",
        "responses": {
          "200": {
            "description": "product and revision, with ETag header"
          }
        }
      },
      "put": {
        "summary": "Publish a partial product update and rebuild pages atomically",
        "security": [
          {
            "softwareToken": []
          }
        ],
        "parameters": [
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "summary": {
                    "type": "string"
                  },
                  "features": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "screenshots": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "url",
                        "caption"
                      ],
                      "properties": {
                        "url": {
                          "type": "string"
                        },
                        "alt": {
                          "type": "string"
                        },
                        "caption": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "compatibility": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "feature_sections": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "releases": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "version",
                        "date",
                        "notes",
                        "file",
                        "size",
                        "sha256",
                        "source_sha",
                        "signature"
                      ]
                    }
                  },
                  "cover": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Optional independent concept cover. Screenshot uploads should update screenshots only; reused screenshot URLs fall back to the concept artwork."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Published; source SHA, catalog revision, publication ID, public URL"
          },
          "403": {
            "description": "Invalid or wrong-product token"
          },
          "409": {
            "description": "Concurrent publication/deployment or immutable release conflict"
          },
          "412": {
            "description": "Stale ETag"
          },
          "422": {
            "description": "Invalid schema, missing asset or checksum mismatch"
          },
          "428": {
            "description": "If-Match required"
          }
        }
      }
    },
    "/api/v1/products/{productId}/assets/{filename}": {
      "parameters": [
        {
          "name": "productId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
          }
        },
        {
          "name": "filename",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "put": {
        "summary": "Upload immutable screenshot/icon/package; does not publish a page",
        "security": [
          {
            "softwareToken": []
          }
        ],
        "parameters": [
          {
            "name": "X-Content-SHA256",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{64}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "file, url, sha256, size"
          },
          "413": {
            "description": "Package >512 MiB or image >15 MiB"
          },
          "422": {
            "description": "Unsupported type, incorrect checksum or image signature"
          }
        }
      }
    }
  }
}
