{
  "openapi": "3.0.3",
  "info": {
    "title": "Kaleo API",
    "version": "2026-10-08",
    "description": "Kaleo AI는 스트리밍 세션을 제어하고, 시청자 분석을 조회하며, Kaleo Connect 장치를 모니터링할 수 있는 웹 API를 제공합니다. 필요에 따라 맞춤형 AVL 제어 및 워크플로우에 API를 통합할 수 있습니다.\n\n시작하려면 아래 지침을 따라 API 키를 발급받고, 교회 ID를 확인하며, 요청을 인증하세요.\n\n## API 키 받기\n\n1. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지로 이동합니다.\n2. 이름을 입력하고 **API 키 생성(Create API key)** 을 선택합니다.\n3. 키를 복사하여 안전하게 보관하세요. 전체 키는 한 번만 표시됩니다.\n\n각 키는 한 교회에서만 작동하며, 생성자는 교회 회원이어야 합니다.\n\n## 교회 ID 찾기\n\n대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 **교회 ID(Church ID)** 를 복사하세요. API 요청 시 `churchId`로 사용합니다.\n\n## 인증\n\n모든 요청에 대해 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사한 키를 정확히 전송하세요:\n\n```text\nAuthorization: Bearer YOUR_API_KEY\n```\n\nAPI 플레이그라운드에서는 복사한 키만 입력하면 됩니다. Bearer는 자동으로 추가됩니다."
  },
  "servers": [
    {
      "url": "https://babel.withkaleo.com",
      "description": "운영 API"
    }
  ],
  "tags": [
    {
      "name": "Languages",
      "description": "지원되는 스피커 및 번역 언어입니다.",
      "x-displayName": "언어"
    },
    {
      "name": "Devices",
      "description": "API를 통해 모니터링 및 원격 제어할 수 있는 Kaleo Connect 장치입니다.",
      "x-displayName": "장치"
    },
    {
      "name": "Streaming",
      "description": "**시작 스트리밍 엔드포인트는 Kaleo Connect 장치에서만 스트리밍 시작에 사용할 수 있습니다.** 이 엔드포인트는 웹 브라우저에서 스트리밍 시작에 사용할 수 없습니다. 다른 모든 스트리밍 엔드포인트는 브라우저와 Kaleo Connect 장치를 모두 제어합니다.",
      "x-displayName": "스트리밍"
    },
    {
      "name": "Sessions",
      "description": "세션 기록 및 시청자 분석입니다.",
      "x-displayName": "세션"
    }
  ],
  "security": [
    {
      "ApiKeyBearer": []
    }
  ],
  "paths": {
    "/v1/church/{churchId}/devices": {
      "get": {
        "operationId": "listDevices",
        "summary": "장치 목록",
        "tags": [
          "Devices"
        ],
        "description": "Kaleo Connect 장치와 해당 기능 준비 상태 목록입니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Devices"
                },
                "example": {
                  "devices": [
                    {
                      "id": "00000000-0000-4000-8000-000000000002",
                      "name": "Sanctuary Mac",
                      "status": "online",
                      "capabilities": [
                        {
                          "capability": "audio-source",
                          "status": "ready"
                        },
                        {
                          "capability": "audio-output",
                          "status": "ready"
                        },
                        {
                          "capability": "propresenter",
                          "status": "unavailable"
                        }
                      ],
                      "lastSeenAt": null
                    }
                  ]
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "503": {
            "description": "일시적인 서비스 또는 인증 실패. 제어 요청을 재시도하기 전에 상태를 조정하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "DEVICES_UNAVAILABLE"
                }
              }
            }
          }
        },
        "x-kaleo-anchor": "List devices"
      }
    },
    "/v1/church/{churchId}/devices/{deviceId}": {
      "get": {
        "operationId": "getDevice",
        "summary": "장치 조회",
        "tags": [
          "Devices"
        ],
        "description": "하나의 Kaleo Connect 장치와 해당 기능 준비 상태를 읽습니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "`GET /devices`에서 가져온 장치 ID입니다."
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceDetails"
                },
                "example": {
                  "device": {
                    "id": "00000000-0000-4000-8000-000000000002",
                    "name": "Sanctuary Mac",
                    "status": "online",
                    "capabilities": [
                      {
                        "capability": "audio-source",
                        "status": "ready"
                      },
                      {
                        "capability": "audio-output",
                        "status": "ready"
                      },
                      {
                        "capability": "propresenter",
                        "status": "unavailable"
                      }
                    ],
                    "lastSeenAt": null
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "404": {
            "description": "이 교회에 장치가 존재하지 않습니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "DEVICE_NOT_FOUND"
                }
              }
            }
          },
          "503": {
            "description": "일시적인 서비스 또는 인증 실패. 제어 요청을 재시도하기 전에 상태를 조정하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "DEVICES_UNAVAILABLE"
                }
              }
            }
          }
        },
        "x-kaleo-anchor": "Get device"
      }
    },
    "/v1/church/{churchId}/streaming": {
      "get": {
        "operationId": "getStreaming",
        "summary": "스트리밍 상태 조회",
        "tags": [
          "Streaming"
        ],
        "description": "현재 세션 및 공유 교회 설정을 읽습니다. 모든 필드가 포함되며, 유휴 상태에서도 포함됩니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamingStatus"
                },
                "example": {
                  "streaming": true,
                  "sessionId": "00000000-0000-4000-8000-000000000001",
                  "startedAt": "2026-10-08T14:00:00.000Z",
                  "deadlineAt": "2026-10-08T16:00:00.000Z",
                  "speakerLanguage": "en",
                  "targetLanguages": [
                    "fr-FR"
                  ],
                  "voice": "male",
                  "visible": true,
                  "publisher": {
                    "kind": "connect",
                    "id": "00000000-0000-4000-8000-000000000002",
                    "name": "Sanctuary Mac"
                  },
                  "phase": "streaming",
                  "streamSettings": {
                    "revision": 4,
                    "settings": {
                      "speakerLanguage": "en",
                      "targetLanguages": [
                        "fr-FR"
                      ],
                      "duration": 3600
                    }
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "503": {
            "description": "일시적인 서비스 또는 인증 실패. 제어 요청을 재시도하기 전에 상태를 조정하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "CONTROL_UNAVAILABLE"
                }
              }
            }
          }
        },
        "x-kaleo-anchor": "Get streaming status"
      }
    },
    "/v1/church/{churchId}/streaming/start": {
      "post": {
        "operationId": "startStreaming",
        "summary": "스트리밍 시작",
        "tags": [
          "Streaming"
        ],
        "description": "저장된 설정을 사용하여 Kaleo Connect 장치에서 스트리밍을 시작합니다. 선택적 본문은 `deviceId`를 선택하고 이 세션에 대한 설정을 재정의할 수 있습니다. `deviceId`이 없으면, Kaleo는 대시보드의 통합(Integrations) 아래 [Kaleo Connect](https://app.withkaleo.com/to/integrations/connect) 페이지에서 구성된 기본 오디오 소스를 선택합니다. 여러 오디오 지원 장치가 있으면 기본값을 사용하거나, 하나만 있으면 해당 장치를 사용합니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamingStatus"
                },
                "example": {
                  "streaming": true,
                  "sessionId": "00000000-0000-4000-8000-000000000001",
                  "startedAt": "2026-10-08T14:00:00.000Z",
                  "deadlineAt": "2026-10-08T16:00:00.000Z",
                  "speakerLanguage": "en",
                  "targetLanguages": [
                    "fr-FR"
                  ],
                  "voice": "male",
                  "visible": true,
                  "publisher": {
                    "kind": "connect",
                    "id": "00000000-0000-4000-8000-000000000002",
                    "name": "Sanctuary Mac"
                  },
                  "phase": "streaming",
                  "streamSettings": {
                    "revision": 4,
                    "settings": {
                      "speakerLanguage": "en",
                      "targetLanguages": [
                        "fr-FR"
                      ],
                      "duration": 3600
                    }
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "잘못된 JSON, 지원되지 않는 필드 또는 유효하지 않은 값.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "INVALID_REQUEST"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "403": {
            "description": "플랜, 언어 또는 사용 제한으로 인해 시작할 수 없음.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "PLAN_LIMIT"
                }
              }
            }
          },
          "409": {
            "description": "활성 세션 충돌, 오디오 소스 누락 또는 기본 선택 누락, 선택한 장치가 준비되지 않음. 스트리밍 상태 및 장치 준비 상태를 확인하세요. 대시보드의 통합(Integrations) 아래 [Kaleo Connect](https://app.withkaleo.com/to/integrations/connect) 페이지에서 기본값을 선택하거나 필요 시 `deviceId`를 제공하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "ACTIVE_SESSION"
                }
              }
            }
          },
          "503": {
            "description": "일시적인 서비스 또는 인증 실패. 제어 요청을 재시도하기 전에 상태를 조정하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "CONTROL_UNAVAILABLE"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartStreaming"
              },
              "examples": {
                "defaultAudioSource": {
                  "summary": "기본 오디오 소스 사용",
                  "value": {}
                },
                "explicitDevice": {
                  "summary": "이 세션에 사용할 장치 선택",
                  "value": {
                    "deviceId": "00000000-0000-4000-8000-000000000002"
                  }
                }
              }
            }
          },
          "description": "본문을 생략하거나 `{}`를 보내면 기본 오디오 소스와 저장된 설정을 사용합니다. `deviceId`를 보내면 이 세션에 대해 다른 장치를 선택합니다."
        },
        "x-kaleo-anchor": "Start streaming"
      }
    },
    "/v1/church/{churchId}/streaming/stop": {
      "post": {
        "operationId": "stopStreaming",
        "summary": "스트리밍 중지",
        "tags": [
          "Streaming"
        ],
        "description": "현재 스트리밍 세션을 중지합니다. 요청 본문은 필요하지 않습니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamingStatus"
                },
                "example": {
                  "streaming": false,
                  "sessionId": null,
                  "startedAt": null,
                  "deadlineAt": null,
                  "speakerLanguage": null,
                  "targetLanguages": [],
                  "voice": "male",
                  "visible": true,
                  "publisher": null,
                  "phase": "idle",
                  "streamSettings": {
                    "revision": 4,
                    "settings": {
                      "speakerLanguage": "en",
                      "targetLanguages": [
                        "fr-FR"
                      ],
                      "duration": 3600
                    }
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "503": {
            "description": "일시적인 서비스 또는 인증 실패. 제어 요청을 재시도하기 전에 상태를 조정하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "CONTROL_UNAVAILABLE"
                }
              }
            }
          }
        },
        "x-kaleo-anchor": "Stop streaming"
      }
    },
    "/v1/church/{churchId}/streaming/voice": {
      "patch": {
        "operationId": "changeVoice",
        "summary": "번역 음성 변경",
        "tags": [
          "Streaming"
        ],
        "description": "유휴 상태 또는 스트리밍 중에 번역 음성을 변경합니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamingStatus"
                },
                "example": {
                  "streaming": true,
                  "sessionId": "00000000-0000-4000-8000-000000000001",
                  "startedAt": "2026-10-08T14:00:00.000Z",
                  "deadlineAt": "2026-10-08T16:00:00.000Z",
                  "speakerLanguage": "en",
                  "targetLanguages": [
                    "fr-FR"
                  ],
                  "voice": "female",
                  "visible": true,
                  "publisher": {
                    "kind": "connect",
                    "id": "00000000-0000-4000-8000-000000000002",
                    "name": "Sanctuary Mac"
                  },
                  "phase": "streaming",
                  "streamSettings": {
                    "revision": 4,
                    "settings": {
                      "speakerLanguage": "en",
                      "targetLanguages": [
                        "fr-FR"
                      ],
                      "duration": 3600
                    }
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "잘못된 JSON, 지원되지 않는 필드 또는 유효하지 않은 값.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "INVALID_REQUEST"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "409": {
            "description": "스트림이 변경되었거나 명령을 확인할 수 없음. 다른 명령을 보내기 전에 현재 스트리밍 상태를 확인하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "SESSION_CHANGED"
                }
              }
            }
          },
          "503": {
            "description": "일시적인 서비스 또는 인증 실패. 제어 요청을 재시도하기 전에 상태를 조정하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "CONTROL_UNAVAILABLE"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeVoice"
              },
              "example": {
                "voice": "female"
              }
            }
          }
        },
        "x-kaleo-anchor": "Change translation voice"
      }
    },
    "/v1/church/{churchId}/streaming/visibility": {
      "patch": {
        "operationId": "changeVisibility",
        "summary": "가시성 변경",
        "tags": [
          "Streaming"
        ],
        "description": "유휴 상태 또는 스트리밍 중에 자막을 표시하거나 숨깁니다. 자막 숨기기는 세션을 중지하지 않습니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamingStatus"
                },
                "example": {
                  "streaming": true,
                  "sessionId": "00000000-0000-4000-8000-000000000001",
                  "startedAt": "2026-10-08T14:00:00.000Z",
                  "deadlineAt": "2026-10-08T16:00:00.000Z",
                  "speakerLanguage": "en",
                  "targetLanguages": [
                    "fr-FR"
                  ],
                  "voice": "male",
                  "visible": false,
                  "publisher": {
                    "kind": "connect",
                    "id": "00000000-0000-4000-8000-000000000002",
                    "name": "Sanctuary Mac"
                  },
                  "phase": "streaming",
                  "streamSettings": {
                    "revision": 4,
                    "settings": {
                      "speakerLanguage": "en",
                      "targetLanguages": [
                        "fr-FR"
                      ],
                      "duration": 3600
                    }
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "잘못된 JSON, 지원되지 않는 필드 또는 유효하지 않은 값.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "INVALID_REQUEST"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "503": {
            "description": "일시적인 서비스 또는 인증 실패. 제어 요청을 재시도하기 전에 상태를 조정하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "CONTROL_UNAVAILABLE"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeVisibility"
              },
              "example": {
                "visible": false
              }
            }
          }
        },
        "x-kaleo-anchor": "Change visibility"
      }
    },
    "/v1/church/{churchId}/streaming/captions/clear": {
      "post": {
        "operationId": "clearCaptions",
        "summary": "자막 지우기",
        "tags": [
          "Streaming"
        ],
        "description": "현재 자막 피드를 지웁니다. 요청 본문은 필요하지 않습니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamingStatus"
                },
                "example": {
                  "streaming": true,
                  "sessionId": "00000000-0000-4000-8000-000000000001",
                  "startedAt": "2026-10-08T14:00:00.000Z",
                  "deadlineAt": "2026-10-08T16:00:00.000Z",
                  "speakerLanguage": "en",
                  "targetLanguages": [
                    "fr-FR"
                  ],
                  "voice": "male",
                  "visible": true,
                  "publisher": {
                    "kind": "connect",
                    "id": "00000000-0000-4000-8000-000000000002",
                    "name": "Sanctuary Mac"
                  },
                  "phase": "streaming",
                  "streamSettings": {
                    "revision": 4,
                    "settings": {
                      "speakerLanguage": "en",
                      "targetLanguages": [
                        "fr-FR"
                      ],
                      "duration": 3600
                    }
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "503": {
            "description": "일시적인 서비스 또는 인증 실패. 제어 요청을 재시도하기 전에 상태를 조정하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "CONTROL_UNAVAILABLE"
                }
              }
            }
          }
        },
        "x-kaleo-anchor": "Clear captions"
      }
    },
    "/v1/church/{churchId}/streaming/deadline": {
      "patch": {
        "operationId": "changeDeadline",
        "summary": "자동 중지 기한 변경",
        "tags": [
          "Streaming"
        ],
        "description": "활성 세션의 자동 중지 시간을 설정합니다. 업데이트된 스트리밍 상태를 반환합니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamingStatus"
                },
                "example": {
                  "streaming": true,
                  "sessionId": "00000000-0000-4000-8000-000000000001",
                  "startedAt": "2026-10-08T14:00:00.000Z",
                  "deadlineAt": "2026-10-08T16:00:00.000Z",
                  "speakerLanguage": "en",
                  "targetLanguages": [
                    "fr-FR"
                  ],
                  "voice": "male",
                  "visible": true,
                  "publisher": {
                    "kind": "connect",
                    "id": "00000000-0000-4000-8000-000000000002",
                    "name": "Sanctuary Mac"
                  },
                  "phase": "streaming",
                  "streamSettings": {
                    "revision": 4,
                    "settings": {
                      "speakerLanguage": "en",
                      "targetLanguages": [
                        "fr-FR"
                      ],
                      "duration": 3600
                    }
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "잘못된 JSON, 지원되지 않는 필드 또는 유효하지 않은 값.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "INVALID_REQUEST"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "409": {
            "description": "유휴 상태일 때 `STREAM_OFFLINE`; 허용된 범위를 벗어난 기한에 대해 `INVALID_DEADLINE`. 다른 명령을 보내기 전에 현재 스트리밍 상태를 확인하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "INVALID_DEADLINE"
                }
              }
            }
          },
          "503": {
            "description": "일시적인 서비스 또는 인증 실패. 제어 요청을 재시도하기 전에 상태를 조정하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "CONTROL_UNAVAILABLE"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeDeadline"
              },
              "example": {
                "deadlineAt": "2026-10-08T16:00:00Z"
              }
            }
          }
        },
        "x-kaleo-anchor": "Change auto-stop deadline"
      }
    },
    "/v1/church/{churchId}/sessions": {
      "get": {
        "operationId": "listSessions",
        "summary": "세션 목록",
        "tags": [
          "Sessions"
        ],
        "description": "최신 순으로 세션 목록과 시청자 분석을 조회합니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "페이지 번호, 1부터 시작합니다. 마지막 페이지를 초과하는 값은 마지막 페이지를 반환합니다."
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 14
            },
            "description": "페이지당 세션 수입니다. 100을 초과하는 값은 100으로 처리됩니다."
          },
          {
            "name": "startedAfter",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "이 시간 이후에 시작된 세션을 포함합니다. Z 또는 시간대 오프셋을 포함하세요."
          },
          {
            "name": "startedBefore",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "이 시간 이전에 시작된 세션을 포함합니다. Z 또는 시간대 오프셋을 포함하세요. `startedAfter` 이후여야 합니다."
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HistoryPage"
                },
                "example": {
                  "sessions": [
                    {
                      "sessionId": "00000000-0000-4000-8000-000000000001",
                      "startedAt": "2026-10-04T14:00:00.000Z",
                      "endedAt": "2026-10-04T15:00:00.000Z",
                      "duration": 3600,
                      "speakerLanguage": "en",
                      "targetLanguages": [
                        "fr-FR"
                      ],
                      "transcriptAvailable": true,
                      "publicSharingEnabled": false,
                      "analytics": {
                        "sessionId": "00000000-0000-4000-8000-000000000001",
                        "status": "finalized",
                        "viewers": 12,
                        "viewerLanguages": {
                          "en": 8,
                          "fr-FR": 6
                        }
                      }
                    }
                  ],
                  "total": 1,
                  "page": 1,
                  "pageSize": 14
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "읽기 응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "잘못된 양의 정수 페이지네이션 또는 잘못되었거나 역전된 타임스탬프 범위.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "INVALID_HISTORY_RANGE"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 교회 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "503": {
            "description": "기록 또는 인증 서비스 사용 불가. 빈 기록 결과가 아님.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "SESSION_HISTORY_UNAVAILABLE"
                }
              }
            }
          }
        },
        "x-kaleo-anchor": "List sessions"
      }
    },
    "/v1/church/{churchId}/sessions/{sessionId}": {
      "get": {
        "operationId": "getSession",
        "summary": "세션 조회",
        "tags": [
          "Sessions"
        ],
        "description": "하나의 세션과 해당 시청자 분석을 읽습니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "`GET /sessions`에서 가져온 세션 ID입니다.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionDetails"
                },
                "example": {
                  "session": {
                    "sessionId": "00000000-0000-4000-8000-000000000001",
                    "startedAt": "2026-10-04T14:00:00.000Z",
                    "endedAt": "2026-10-04T15:00:00.000Z",
                    "duration": 3600,
                    "speakerLanguage": "en",
                    "targetLanguages": [
                      "fr-FR"
                    ],
                    "transcriptAvailable": true,
                    "publicSharingEnabled": false,
                    "analytics": {
                      "sessionId": "00000000-0000-4000-8000-000000000001",
                      "status": "finalized",
                      "viewers": 12,
                      "viewerLanguages": {
                        "en": 8,
                        "fr-FR": 6
                      }
                    }
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "읽기 응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 교회 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "404": {
            "description": "누락, 제거, 잘못된 ID 또는 소유자가 다른 세션.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "SESSION_NOT_FOUND"
                }
              }
            }
          },
          "503": {
            "description": "기록 또는 인증 서비스 사용 불가.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "SESSION_HISTORY_UNAVAILABLE"
                }
              }
            }
          }
        },
        "x-kaleo-anchor": "Get session"
      }
    },
    "/v1/church/{churchId}/languages/speaker": {
      "get": {
        "operationId": "listSpeakerLanguages",
        "summary": "스피커 언어 목록",
        "tags": [
          "Languages"
        ],
        "description": "지원되는 스피커 언어 목록입니다. `speakerLanguage`에서 이 코드를 사용하세요.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Languages"
                },
                "example": {
                  "languages": [
                    {
                      "code": "en",
                      "name": "English",
                      "nativeName": "English",
                      "emoji": "🌎"
                    }
                  ]
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "503": {
            "description": "인증 서비스가 일시적으로 사용 불가입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "AUTHENTICATION_UNAVAILABLE"
                }
              }
            }
          }
        },
        "x-kaleo-anchor": "List speaker languages"
      }
    },
    "/v1/church/{churchId}/languages/target": {
      "get": {
        "operationId": "listTargetLanguages",
        "summary": "대상 언어 목록",
        "tags": [
          "Languages"
        ],
        "description": "지원되는 번역 언어 목록입니다. `targetLanguages`에서 이 코드를 사용하세요.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Languages"
                },
                "example": {
                  "languages": [
                    {
                      "code": "en",
                      "name": "English",
                      "nativeName": "English",
                      "emoji": "🌎"
                    }
                  ]
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "503": {
            "description": "인증 서비스가 일시적으로 사용 불가입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "AUTHENTICATION_UNAVAILABLE"
                }
              }
            }
          }
        },
        "x-kaleo-anchor": "List target languages"
      }
    },
    "/v1/church/{churchId}/languages/{code}": {
      "get": {
        "operationId": "getLanguage",
        "summary": "언어 조회",
        "tags": [
          "Languages"
        ],
        "description": "지원되는 하나의 언어 코드에 대한 이름과 이모지를 읽습니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "정확한 언어 코드, 예: `en` 또는 `zh-Hans`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LanguageDetails"
                },
                "example": {
                  "language": {
                    "code": "fr",
                    "name": "French (General)",
                    "nativeName": "Français",
                    "emoji": "🇫🇷"
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "404": {
            "description": "지원되지 않는 언어 코드입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "LANGUAGE_NOT_FOUND"
                }
              }
            }
          },
          "503": {
            "description": "인증 서비스가 일시적으로 사용 불가입니다.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "AUTHENTICATION_UNAVAILABLE"
                }
              }
            }
          }
        },
        "x-kaleo-anchor": "Get language"
      }
    },
    "/v1/church/{churchId}/streaming/deadline/adjust": {
      "post": {
        "operationId": "adjustDeadline",
        "summary": "자동 중지 시간 조정",
        "tags": [
          "Streaming"
        ],
        "description": "자동 중지 시간을 더하거나 뺍니다. 유휴 상태에서는 다음 수동 시작의 지속 시간을 변경하고, 스트리밍 중에는 현재 기한을 변경합니다. 각 요청은 별도의 조정을 적용합니다.",
        "parameters": [
          {
            "name": "churchId",
            "in": "path",
            "required": true,
            "description": "교회 ID입니다. 대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사하세요.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamingStatus"
                },
                "example": {
                  "streaming": true,
                  "sessionId": "00000000-0000-4000-8000-000000000001",
                  "startedAt": "2026-10-08T14:00:00.000Z",
                  "deadlineAt": "2026-10-08T16:00:00.000Z",
                  "speakerLanguage": "en",
                  "targetLanguages": [
                    "fr-FR"
                  ],
                  "voice": "male",
                  "visible": true,
                  "publisher": {
                    "kind": "connect",
                    "id": "00000000-0000-4000-8000-000000000002",
                    "name": "Sanctuary Mac"
                  },
                  "phase": "streaming",
                  "streamSettings": {
                    "revision": 4,
                    "settings": {
                      "speakerLanguage": "en",
                      "targetLanguages": [
                        "fr-FR"
                      ],
                      "duration": 3600
                    }
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "응답은 캐시되지 않습니다.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "잘못된 JSON, 지원되지 않는 필드 또는 유효하지 않은 값.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "INVALID_REQUEST"
                }
              }
            }
          },
          "401": {
            "description": "API 키가 없거나 유효하지 않음(만료, 취소, 잘못된 교회, 소유자가 더 이상 회원이 아님 포함).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "API_KEY_INVALID"
                }
              }
            }
          },
          "409": {
            "description": "허용된 범위를 벗어난 라이브 기한에 대해 `INVALID_DEADLINE`; 세션에 기한이 없을 때 `DEADLINE_NOT_SET`. 유휴 설정 또는 입장 변경이 동시에 발생했을 때 `SETTINGS_CHANGED` 또는 `SESSION_ACTIVE`. 다른 명령을 보내기 전에 현재 스트리밍 상태를 확인하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "INVALID_DEADLINE"
                }
              }
            }
          },
          "503": {
            "description": "일시적인 서비스 또는 인증 실패. 제어 요청을 재시도하기 전에 상태를 조정하세요.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "error": "CONTROL_UNAVAILABLE"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdjustDeadline"
              },
              "example": {
                "deltaSeconds": 120
              }
            }
          }
        },
        "x-kaleo-anchor": "Adjust auto-stop time"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key",
        "description": "대시보드의 통합(Integrations) 아래 [API](https://app.withkaleo.com/to/integrations/api) 페이지에서 복사한 API 키를 정확히 입력하세요. Bearer는 자동으로 추가됩니다. 생성자가 회원인 동안 한 교회에서 작동합니다."
      }
    },
    "schemas": {
      "Device": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "장치 ID입니다. 요청 시 `deviceId`로 전달하세요."
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "offline",
              "online",
              "maintenance"
            ],
            "description": "연결 상태입니다. 90초간 연락 없으면 오프라인; 유지보수는 일시적 사용 불가를 의미합니다."
          },
          "capabilities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeviceCapability"
            },
            "description": "이 장치의 각 기능 준비 상태입니다."
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Kaleo와 마지막 연락 시각; 알 수 없으면 `null`입니다."
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "capabilities",
          "lastSeenAt"
        ],
        "additionalProperties": false
      },
      "DeviceCapability": {
        "type": "object",
        "properties": {
          "capability": {
            "type": "string",
            "enum": [
              "audio-source",
              "audio-output",
              "propresenter"
            ],
            "description": "로컬 기능: 오디오 캡처, 번역 음성 재생 또는 ProPresenter 슬라이드 입력."
          },
          "status": {
            "type": "string",
            "enum": [
              "ready",
              "unavailable",
              "offline"
            ],
            "description": "이 기능을 사용할 준비가 되었는지 여부입니다."
          }
        },
        "required": [
          "capability",
          "status"
        ],
        "additionalProperties": false
      },
      "Devices": {
        "type": "object",
        "properties": {
          "devices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Device"
            }
          }
        },
        "required": [
          "devices"
        ],
        "additionalProperties": false
      },
      "DeviceDetails": {
        "type": "object",
        "properties": {
          "device": {
            "$ref": "#/components/schemas/Device"
          }
        },
        "required": [
          "device"
        ],
        "additionalProperties": false
      },
      "ProPresenterSelection": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "default"
                ],
                "description": "교회의 기본 ProPresenter 장치를 사용합니다."
              }
            },
            "required": [
              "mode"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "none"
                ],
                "description": "이 세션에서 ProPresenter를 사용하지 않습니다."
              }
            },
            "required": [
              "mode"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "device"
                ],
                "description": "`deviceId`로 지정된 장치를 사용합니다."
              },
              "deviceId": {
                "type": "string",
                "description": "ProPresenter 소스의 장치 ID로, `GET /devices`에서 가져옵니다. 오디오 소스와 다를 수 있습니다."
              }
            },
            "required": [
              "mode",
              "deviceId"
            ],
            "additionalProperties": false
          }
        ],
        "description": "이 세션에 사용할 ProPresenter 소스를 선택합니다. 연결은 Connect에서 구성하세요."
      },
      "StartStreaming": {
        "type": "object",
        "properties": {
          "deviceId": {
            "type": "string",
            "description": "선택적 오디오 소스 장치 ID로, `GET /devices`에서 가져옵니다. 이 세션에 대해 교회 기본값을 재정의합니다. 생략하면 저장된 기본 오디오 소스 또는 단일 오디오 소스 지원 장치를 사용합니다. 여러 장치가 있고 기본값이 없으면 선택이 필요합니다. 선택한 장치는 준비되어 있어야 합니다."
          },
          "overrides": {
            "type": "object",
            "properties": {
              "speakerLanguage": {
                "type": "string",
                "description": "`GET /languages/speaker`에서 가져온 코드입니다. 다국어 모드에는 `\"mul\"`를 사용하세요."
              },
              "targetLanguages": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "minItems": 1,
                "description": "`GET /languages/target`에서 가져온 코드입니다. 플랜 한도 내에서 지원되는 모든 대상에 `[\"ALL\"]`를 사용하세요."
              },
              "duration": {
                "type": "integer",
                "minimum": 60,
                "maximum": 21600,
                "description": "자동 중지까지의 시간(초)입니다."
              },
              "proPresenter": {
                "$ref": "#/components/schemas/ProPresenterSelection"
              }
            },
            "required": [],
            "additionalProperties": false,
            "description": "이 세션에만 적용되는 설정입니다. 생략된 필드는 저장된 기본값을 사용합니다."
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "ChangeVoice": {
        "type": "object",
        "properties": {
          "voice": {
            "type": "string",
            "enum": [
              "male",
              "female"
            ],
            "description": "번역 음성입니다. 유휴 또는 스트리밍 중에 변경할 수 있습니다."
          }
        },
        "required": [
          "voice"
        ],
        "additionalProperties": false
      },
      "ChangeVisibility": {
        "type": "object",
        "properties": {
          "visible": {
            "type": "boolean",
            "description": "`true`는 자막을 표시하고; `false`는 스트리밍을 계속하면서 자막을 숨깁니다."
          }
        },
        "required": [
          "visible"
        ],
        "additionalProperties": false
      },
      "ChangeDeadline": {
        "type": "object",
        "properties": {
          "deadlineAt": {
            "type": "string",
            "format": "date-time",
            "description": "Z 또는 시간대 오프셋이 포함된 미래 자동 중지 시간입니다. `startedAt` 이후 6시간 이내여야 합니다."
          }
        },
        "required": [
          "deadlineAt"
        ],
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "success",
          "error"
        ]
      },
      "Analytics": {
        "type": "object",
        "properties": {
          "sessionId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "live",
              "pending",
              "finalized"
            ],
            "description": "`live`: 잠정 집계; `pending`: 최종 집계 대기 중; `finalized`: 저장된 집계."
          },
          "viewers": {
            "type": "integer",
            "minimum": 0,
            "nullable": true,
            "description": "세션의 고유 시청자 ID입니다. 현재 시청자가 아닙니다. 사용할 수 없으면 `null`; 0은 시청자 없음입니다."
          },
          "viewerLanguages": {
            "type": "object",
            "nullable": true,
            "additionalProperties": {
              "type": "integer",
              "minimum": 0
            },
            "description": "언어 코드별 시청자 분석입니다. 한 시청자가 여러 언어에 나타날 수 있습니다. 사용할 수 없으면 `null`입니다."
          }
        },
        "required": [
          "sessionId",
          "status",
          "viewers",
          "viewerLanguages"
        ]
      },
      "HistorySession": {
        "type": "object",
        "properties": {
          "sessionId": {
            "type": "string"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "endedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "세션 종료 시간; 미완료 또는 알 수 없으면 `null`입니다."
          },
          "duration": {
            "type": "integer",
            "nullable": true,
            "description": "기록된 세션 길이(초); 미완료 또는 알 수 없으면 `null`입니다."
          },
          "speakerLanguage": {
            "type": "string",
            "nullable": true,
            "description": "스피커 언어 코드; 기록되지 않으면 `null`입니다."
          },
          "targetLanguages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "기록된 번역 언어 코드 또는 `[\"ALL\"]`입니다."
          },
          "transcriptAvailable": {
            "type": "boolean",
            "description": "저장된 기록이 준비되었을 때 `true`입니다. 공개 접근이나 다운로드 URL을 제공하지 않습니다."
          },
          "publicSharingEnabled": {
            "type": "boolean",
            "description": "완료된 세션에 대해 공개 공유가 활성화되었을 때 `true`입니다."
          },
          "analytics": {
            "$ref": "#/components/schemas/Analytics"
          }
        },
        "required": [
          "sessionId",
          "startedAt",
          "endedAt",
          "duration",
          "speakerLanguage",
          "targetLanguages",
          "transcriptAvailable",
          "publicSharingEnabled",
          "analytics"
        ]
      },
      "HistoryPage": {
        "type": "object",
        "properties": {
          "sessions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HistorySession"
            }
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "description": "필터에 맞는 총 세션 수(모든 페이지 합계)."
          },
          "page": {
            "type": "integer",
            "minimum": 1,
            "description": "반환된 페이지; 요청한 페이지보다 낮을 수 있습니다."
          },
          "pageSize": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "페이지당 최대 세션 수, 최대 100."
          }
        },
        "required": [
          "sessions",
          "total",
          "page",
          "pageSize"
        ]
      },
      "SessionDetails": {
        "type": "object",
        "properties": {
          "session": {
            "$ref": "#/components/schemas/HistorySession"
          }
        },
        "required": [
          "session"
        ]
      },
      "Language": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "언어 필드에 이 정확한 코드를 사용하세요."
          },
          "name": {
            "type": "string",
            "description": "영어 표시 이름입니다."
          },
          "nativeName": {
            "type": "string",
            "description": "자국어 이름; 없으면 영어 이름입니다."
          },
          "emoji": {
            "type": "string",
            "description": "이 언어를 표시하는 이모지입니다."
          }
        },
        "required": [
          "code",
          "name",
          "nativeName",
          "emoji"
        ],
        "additionalProperties": false
      },
      "Languages": {
        "type": "object",
        "properties": {
          "languages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Language"
            }
          }
        },
        "required": [
          "languages"
        ],
        "additionalProperties": false
      },
      "LanguageDetails": {
        "type": "object",
        "properties": {
          "language": {
            "$ref": "#/components/schemas/Language"
          }
        },
        "required": [
          "language"
        ],
        "additionalProperties": false
      },
      "StreamingStatus": {
        "type": "object",
        "properties": {
          "streaming": {
            "type": "boolean",
            "description": "활성 세션 중인 `true`입니다. 시작, 재연결, 종료 포함. 오디오 도착 여부는 확인하지 않습니다."
          },
          "sessionId": {
            "type": "string",
            "nullable": true,
            "description": "현재 세션 ID; 유휴 시 `null`입니다."
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "현재 세션 시작 시간; 유휴 시 `null`입니다."
          },
          "deadlineAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "자동 중지 시간; 유휴 시 또는 기한이 없으면 `null`입니다."
          },
          "speakerLanguage": {
            "type": "string",
            "nullable": true,
            "description": "현재 스피커 언어 코드; 유휴 시 `null`입니다."
          },
          "targetLanguages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "현재 번역 언어 코드; 유휴 시 비어 있음."
          },
          "voice": {
            "type": "string",
            "enum": [
              "male",
              "female",
              null
            ],
            "nullable": false,
            "description": "번역 음성, 유휴 시 포함."
          },
          "visible": {
            "type": "boolean",
            "description": "`true`는 자막을 표시하고; `false`는 숨깁니다. 유휴 시에도 적용됩니다."
          },
          "publisher": {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "browser",
                  "connect"
                ]
              },
              "id": {
                "type": "string",
                "description": "`kind`가 `connect`일 때 장치 ID; `kind`가 `browser`일 때 브라우저 게시자 ID."
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "kind",
              "id",
              "name"
            ],
            "additionalProperties": false,
            "nullable": true,
            "description": "오디오를 전송하는 Kaleo Connect 장치 또는 브라우저; 유휴 시 `null`입니다."
          },
          "phase": {
            "type": "string",
            "enum": [
              "idle",
              "starting",
              "streaming",
              "reconnecting",
              "ending"
            ],
            "description": "세션 단계; 유휴는 세션이 활성화되지 않음을 의미합니다."
          },
          "streamSettings": {
            "type": "object",
            "description": "다음 수동 시작을 위한 교회 기본값입니다. 활성 세션 재정의는 이 값을 변경하지 않습니다.",
            "required": [
              "revision",
              "settings"
            ],
            "properties": {
              "revision": {
                "type": "integer",
                "minimum": 0,
                "description": "이 기본값이 변경될 때 증가합니다."
              },
              "settings": {
                "type": "object",
                "required": [
                  "speakerLanguage",
                  "targetLanguages",
                  "duration"
                ],
                "properties": {
                  "speakerLanguage": {
                    "type": "string",
                    "description": "기본 스피커 언어 코드입니다."
                  },
                  "targetLanguages": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "기본 번역 언어 코드; `[\"ALL\"]`는 지원되는 모든 대상을 선택합니다."
                  },
                  "duration": {
                    "type": "integer",
                    "minimum": 60,
                    "maximum": 21600,
                    "description": "자동 중지까지의 시간(초)입니다."
                  }
                }
              }
            }
          }
        },
        "required": [
          "streaming",
          "phase",
          "sessionId",
          "startedAt",
          "deadlineAt",
          "speakerLanguage",
          "targetLanguages",
          "voice",
          "visible",
          "publisher",
          "streamSettings"
        ],
        "additionalProperties": false,
        "description": "현재 세션 및 공유 교회 설정입니다. 모든 필드가 포함되며, 유휴 상태에서도 포함됩니다."
      },
      "AdjustDeadline": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "deltaSeconds"
        ],
        "properties": {
          "deltaSeconds": {
            "type": "integer",
            "minimum": -21600,
            "maximum": 21600,
            "description": "유휴 지속 시간 또는 현재 기한에 더할 초 단위 값입니다; 음수는 빼기입니다. 0일 수 없습니다. 유휴 지속 시간: 60–21600초. 라이브 기한: `startedAt` 이후 6시간 이내의 미래.",
            "not": {
              "enum": [
                0
              ]
            }
          }
        }
      }
    }
  }
}
