{
  "openapi": "3.1.0",
  "info": {
    "title": "SongCollect API",
    "description": "Versioned, language-independent SongCollect interface. Browser sessions use an HttpOnly cookie. Every mutation requires the configured APP_ORIGIN header; native clients must retain the cookie and send that origin too. Native token authentication and cross-origin browser hosting are future work. Repeated Idempotency-Key requests replay the committed response; PUT requires the quoted revision ETag in If-Match. Public routes expose active song heads only.",
    "version": "1.0.0"
  },
  "paths": {
    "/api/health/live": {
      "get": {
        "operationId": "live",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/health/ready": {
      "get": {
        "operationId": "ready",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/churches": {
      "get": {
        "operationId": "churches",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Churches"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/churches/{churchId}/assets": {
      "post": {
        "operationId": "upload",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "filename",
            "in": "query",
            "description": "Original file name shown to readers.",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 255,
              "minLength": 1
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "PDF bytes, at most 20 MB",
          "content": {
            "application/pdf": {
              "schema": {
                "$ref": "#/components/schemas/PdfBytes"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Checked and stored; ready to attach",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetResponse"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "408": {
            "description": "The body stalled for 30 s or took over 5 minutes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "File larger than 20 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "415": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "The file is not a usable PDF",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Too many uploads in progress; retry shortly",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/churches/{churchId}/assets/{assetId}/content": {
      "get": {
        "operationId": "download",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "assetId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "download",
            "in": "query",
            "description": "Send `attachment` instead of `inline` as the Content-Disposition.",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Single byte range, e.g. bytes=0-1023",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File bytes; ETag is the quoted SHA-256",
            "content": {
              "application/pdf": {}
            }
          },
          "206": {
            "description": "Requested byte range",
            "content": {
              "application/pdf": {}
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "416": {
            "description": "Range not satisfiable"
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/churches/{churchId}/songs": {
      "get": {
        "operationId": "list",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "maximum": 100000,
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Catalogue"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      },
      "post": {
        "operationId": "create",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MetadataInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              },
              "Location": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SongResponse"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/churches/{churchId}/songs/{songId}": {
      "get": {
        "operationId": "get",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Quoted current revision"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SongResponse"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      },
      "put": {
        "operationId": "update",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "description": "Strong ETag from the base revision, e.g. \"1\"",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MetadataInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SongResponse"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "412": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "428": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/churches/{churchId}/songs/{songId}/arrangements": {
      "get": {
        "operationId": "list_arrangements",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Arrangements"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      },
      "post": {
        "operationId": "create_arrangement",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ArrangementDocument"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              },
              "Location": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArrangementResponse"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/churches/{churchId}/songs/{songId}/arrangements/{arrangementId}": {
      "get": {
        "operationId": "get_arrangement",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "arrangementId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Quoted current arrangement version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArrangementResponse"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      },
      "put": {
        "operationId": "update_arrangement",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "arrangementId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "description": "Strong ETag of the base arrangement version, e.g. \"1\"",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ArrangementDocument"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArrangementResponse"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "412": {
            "description": "Stale version; currentArrangement holds the latest revision",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "428": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/churches/{churchId}/songs/{songId}/arrangements/{arrangementId}/revisions": {
      "get": {
        "operationId": "arrangement_revisions",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "arrangementId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "beforeVersion",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "maximum": 2147483647,
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArrangementRevisions"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/churches/{churchId}/songs/{songId}/lyrics": {
      "get": {
        "operationId": "list_lyrics",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LyricVersions"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      },
      "post": {
        "operationId": "create_lyrics",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NewLyrics"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              },
              "Location": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LyricVersionResponse"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/churches/{churchId}/songs/{songId}/lyrics/{lyricVersionId}": {
      "get": {
        "operationId": "get_lyrics",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "lyricVersionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Quoted current lyric version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LyricVersionResponse"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      },
      "put": {
        "operationId": "update_lyrics",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "lyricVersionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "description": "Strong ETag of the base lyric version, e.g. \"1\"",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LyricsDocument"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LyricVersionResponse"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "412": {
            "description": "Stale version; currentLyrics holds the latest revision",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "428": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/churches/{churchId}/songs/{songId}/lyrics/{lyricVersionId}/revisions": {
      "get": {
        "operationId": "lyric_revisions",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "lyricVersionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "beforeVersion",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "maximum": 2147483647,
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LyricRevisions"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/churches/{churchId}/songs/{songId}/revisions": {
      "get": {
        "operationId": "revisions",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "beforeVersion",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "maximum": 2147483647,
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Revisions"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "developmentSession": []
          }
        ]
      }
    },
    "/api/v1/public/churches/{churchId}/assets/{assetId}/content": {
      "get": {
        "operationId": "public_download",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "assetId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "download",
            "in": "query",
            "description": "Send `attachment` instead of `inline` as the Content-Disposition.",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Files of current arrangements of active songs only",
            "content": {
              "application/pdf": {}
            }
          },
          "206": {
            "content": {
              "application/pdf": {}
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "416": {
            "description": "Range not satisfiable"
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/churches/{churchId}/songs": {
      "get": {
        "operationId": "public_list",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "maximum": 100000,
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Catalogue"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/churches/{churchId}/songs/{songId}": {
      "get": {
        "operationId": "public_get",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SongResponse"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/churches/{churchId}/songs/{songId}/arrangements": {
      "get": {
        "operationId": "public_arrangements",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Arrangements"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/churches/{churchId}/songs/{songId}/lyrics": {
      "get": {
        "operationId": "public_lyrics",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "songId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LyricVersions"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/session": {
      "post": {
        "operationId": "login",
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "description": "Configured APP_ORIGIN",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Credentials"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Signed in; HttpOnly session cookie set"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "logout",
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Session revoked and cookie cleared"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Arrangement": {
        "type": "object",
        "required": [
          "id",
          "songId",
          "version",
          "revisionId",
          "label",
          "lyricVersionIds",
          "files",
          "updatedAt"
        ],
        "properties": {
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Asset"
            },
            "description": "Files in display order; the first is the main file."
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string"
          },
          "lyricVersionIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "revisionId": {
            "type": "string",
            "format": "uuid"
          },
          "songId": {
            "type": "string",
            "format": "uuid"
          },
          "sourceKey": {
            "type": [
              "string",
              "null"
            ]
          },
          "tempo": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer",
            "format": "int32",
            "description": "Increments with each saved revision; send it quoted in If-Match."
          }
        }
      },
      "ArrangementDocument": {
        "type": "object",
        "description": "The revisioned content of an arrangement. Files are referenced by asset ID\nin display order; the first file is the main one.",
        "required": [
          "label",
          "lyricVersionIds",
          "assetIds"
        ],
        "properties": {
          "assetIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Ready assets of the church; the first is the main file.",
            "maxItems": 20
          },
          "label": {
            "type": "string",
            "description": "Name such as \"Standard\" or \"Band\".",
            "maxLength": 80,
            "minLength": 1
          },
          "lyricVersionIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Lyric versions of the same song this arrangement is used with.",
            "maxItems": 20
          },
          "sourceKey": {
            "type": [
              "string",
              "null"
            ],
            "description": "Key the material is written in, such as `D` or `F#m`.",
            "example": "D",
            "maxLength": 3
          },
          "tempo": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Beats per minute.",
            "maximum": 400,
            "minimum": 20
          }
        },
        "additionalProperties": false
      },
      "ArrangementResponse": {
        "type": "object",
        "required": [
          "arrangement"
        ],
        "properties": {
          "arrangement": {
            "$ref": "#/components/schemas/Arrangement"
          }
        }
      },
      "ArrangementRevision": {
        "type": "object",
        "required": [
          "id",
          "version",
          "label",
          "lyricVersionIds",
          "files",
          "createdAt"
        ],
        "properties": {
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Asset"
            }
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string"
          },
          "lyricVersionIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "sourceKey": {
            "type": [
              "string",
              "null"
            ]
          },
          "tempo": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "version": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "ArrangementRevisions": {
        "type": "object",
        "required": [
          "revisions",
          "hasMore"
        ],
        "properties": {
          "hasMore": {
            "type": "boolean"
          },
          "revisions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArrangementRevision"
            },
            "maxItems": 50
          }
        }
      },
      "Arrangements": {
        "type": "object",
        "required": [
          "arrangements"
        ],
        "properties": {
          "arrangements": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Arrangement"
            },
            "maxItems": 20
          }
        }
      },
      "Asset": {
        "type": "object",
        "description": "A checked, immutable file such as a sheet-music PDF.",
        "required": [
          "id",
          "filename",
          "mediaType",
          "size",
          "sha256",
          "createdAt"
        ],
        "properties": {
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "filename": {
            "type": "string"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "mediaType": {
            "type": "string",
            "example": "application/pdf"
          },
          "pageCount": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64"
          },
          "sha256": {
            "type": "string",
            "description": "Lowercase hex SHA-256 of the bytes; also the download ETag."
          },
          "size": {
            "type": "integer",
            "format": "int64",
            "description": "Size in bytes."
          }
        }
      },
      "AssetResponse": {
        "type": "object",
        "required": [
          "asset"
        ],
        "properties": {
          "asset": {
            "$ref": "#/components/schemas/Asset"
          }
        }
      },
      "Catalogue": {
        "type": "object",
        "required": [
          "church",
          "songs",
          "hasMore",
          "lyricMatches",
          "sheetMusicSongIds"
        ],
        "properties": {
          "church": {
            "$ref": "#/components/schemas/Church"
          },
          "hasMore": {
            "type": "boolean"
          },
          "lyricMatches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LyricMatch"
            },
            "description": "Lyric versions of the listed songs whose text matched the search."
          },
          "sheetMusicSongIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Listed songs with at least one sheet-music file in a current arrangement."
          },
          "songs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Song"
            }
          }
        }
      },
      "Church": {
        "type": "object",
        "required": [
          "id",
          "name",
          "timeZone"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "role": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Role"
              },
              {
                "type": "null"
              }
            ]
          },
          "timeZone": {
            "type": "string"
          }
        }
      },
      "Churches": {
        "type": "object",
        "required": [
          "churches"
        ],
        "properties": {
          "churches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Church"
            }
          }
        }
      },
      "Credentials": {
        "type": "object",
        "required": [
          "email",
          "password"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "password": {
            "type": "string",
            "maxLength": 256,
            "minLength": 1
          }
        },
        "additionalProperties": false
      },
      "ErrorBody": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "current": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Song"
              },
              {
                "type": "null"
              }
            ]
          },
          "currentArrangement": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Arrangement",
                "description": "The current arrangement when an arrangement save is rejected as stale."
              },
              {
                "type": "null"
              }
            ]
          },
          "currentLyrics": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LyricVersion",
                "description": "The current lyric version when a lyric save is rejected as stale."
              },
              {
                "type": "null"
              }
            ]
          },
          "error": {
            "type": "string"
          }
        }
      },
      "Health": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string"
          }
        }
      },
      "LyricLine": {
        "type": "object",
        "required": [
          "id",
          "text"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Stable line identity. Keep it when editing the text; generate a new\nUUID for an added line."
          },
          "text": {
            "type": "string",
            "maxLength": 200
          }
        },
        "additionalProperties": false
      },
      "LyricMatch": {
        "type": "object",
        "required": [
          "songId",
          "lyricVersionId",
          "language",
          "label"
        ],
        "properties": {
          "label": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "lyricVersionId": {
            "type": "string",
            "format": "uuid"
          },
          "songId": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "LyricRevision": {
        "type": "object",
        "required": [
          "id",
          "version",
          "label",
          "sections",
          "sequence",
          "createdAt"
        ],
        "properties": {
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string"
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LyricSection"
            }
          },
          "sequence": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "version": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "LyricRevisions": {
        "type": "object",
        "required": [
          "revisions",
          "hasMore"
        ],
        "properties": {
          "hasMore": {
            "type": "boolean"
          },
          "revisions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LyricRevision"
            },
            "maxItems": 50
          }
        }
      },
      "LyricSection": {
        "type": "object",
        "required": [
          "id",
          "name",
          "lines"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Stable section identity referenced by singing sequences."
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LyricLine"
            },
            "maxItems": 200,
            "minItems": 1
          },
          "name": {
            "type": "string",
            "description": "Display name such as \"Verse 1\" or \"Chorus\"; unique within the document.",
            "maxLength": 80,
            "minLength": 1
          }
        },
        "additionalProperties": false
      },
      "LyricVersion": {
        "type": "object",
        "required": [
          "id",
          "songId",
          "language",
          "version",
          "revisionId",
          "label",
          "sections",
          "sequence",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "revisionId": {
            "type": "string",
            "format": "uuid"
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LyricSection"
            }
          },
          "sequence": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "songId": {
            "type": "string",
            "format": "uuid"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer",
            "format": "int32",
            "description": "Increments with each saved revision; send it quoted in If-Match."
          }
        }
      },
      "LyricVersionResponse": {
        "type": "object",
        "required": [
          "lyrics"
        ],
        "properties": {
          "lyrics": {
            "$ref": "#/components/schemas/LyricVersion"
          }
        }
      },
      "LyricVersions": {
        "type": "object",
        "required": [
          "lyrics"
        ],
        "properties": {
          "lyrics": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LyricVersion"
            },
            "description": "Lyric versions of the song, ordered by language and creation.",
            "maxItems": 20
          }
        }
      },
      "LyricsDocument": {
        "type": "object",
        "description": "The revisioned content of a lyric version.",
        "required": [
          "label",
          "sections",
          "sequence"
        ],
        "properties": {
          "label": {
            "type": "string",
            "description": "Edition label such as \"Original\" or \"Simplified\".",
            "maxLength": 80
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LyricSection"
            },
            "maxItems": 40,
            "minItems": 1
          },
          "sequence": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Default singing sequence as section IDs. Sections may repeat. Empty\nmeans the section order is sung.",
            "maxItems": 100
          }
        },
        "additionalProperties": false
      },
      "Metadata": {
        "type": "object",
        "required": [
          "title",
          "alternateTitles",
          "authors",
          "copyright",
          "themes",
          "songbooks"
        ],
        "properties": {
          "alternateTitles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 20
          },
          "authors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 30
          },
          "copyright": {
            "type": "string",
            "maxLength": 1000
          },
          "songbooks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Songbook"
            },
            "maxItems": 30
          },
          "themes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 30
          },
          "title": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1
          }
        },
        "additionalProperties": false
      },
      "MetadataInput": {
        "type": "object",
        "required": [
          "title"
        ],
        "properties": {
          "alternateTitles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 20
          },
          "authors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 30
          },
          "copyright": {
            "type": "string",
            "maxLength": 1000
          },
          "songbooks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Songbook"
            },
            "maxItems": 30
          },
          "themes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 30
          },
          "title": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1
          }
        },
        "additionalProperties": false
      },
      "NewLyrics": {
        "type": "object",
        "required": [
          "language",
          "label",
          "sections",
          "sequence"
        ],
        "properties": {
          "label": {
            "type": "string",
            "maxLength": 80
          },
          "language": {
            "type": "string",
            "description": "BCP 47 language tag, fixed for the lifetime of the lyric version.",
            "example": "de",
            "maxLength": 35,
            "minLength": 2
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LyricSection"
            },
            "maxItems": 40,
            "minItems": 1
          },
          "sequence": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "maxItems": 100
          }
        },
        "additionalProperties": false
      },
      "PdfBytes": {
        "type": "string",
        "format": "binary",
        "description": "Raw PDF bytes, described as a binary string in OpenAPI."
      },
      "Revision": {
        "type": "object",
        "required": [
          "id",
          "version",
          "metadata",
          "createdAt"
        ],
        "properties": {
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          },
          "version": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "Revisions": {
        "type": "object",
        "required": [
          "revisions",
          "hasMore"
        ],
        "properties": {
          "hasMore": {
            "type": "boolean"
          },
          "revisions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Revision"
            },
            "maxItems": 50
          }
        }
      },
      "Role": {
        "type": "string",
        "enum": [
          "Administrator",
          "Editor",
          "Viewer"
        ]
      },
      "Song": {
        "type": "object",
        "required": [
          "id",
          "version",
          "revisionId",
          "metadata",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          },
          "revisionId": {
            "type": "string",
            "format": "uuid"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "SongResponse": {
        "type": "object",
        "required": [
          "song"
        ],
        "properties": {
          "song": {
            "$ref": "#/components/schemas/Song"
          }
        }
      },
      "Songbook": {
        "type": "object",
        "required": [
          "book",
          "number"
        ],
        "properties": {
          "book": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1
          },
          "number": {
            "type": "string",
            "maxLength": 30,
            "minLength": 1
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "developmentSession": {
        "type": "apiKey",
        "in": "cookie",
        "name": "songcollect"
      },
      "session": {
        "type": "apiKey",
        "in": "cookie",
        "name": "__Host-songcollect"
      }
    }
  }
}
