{
  "openapi": "3.1.0",
  "info": {
    "title": "Kokoro TTS API",
    "description": "API for text-to-speech generation using Kokoro",
    "version": "0.6.0-rc1"
  },
  "paths": {
    "/v1/audio/speech": {
      "post": {
        "tags": [
          "OpenAI Compatible TTS"
        ],
        "summary": "Create Speech",
        "description": "OpenAI-compatible endpoint for text-to-speech",
        "operationId": "create_speech_v1_audio_speech_post",
        "parameters": [
          {
            "name": "x-raw-response",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "title": "X-Raw-Response"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpenAISpeechRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/download/{filename}": {
      "get": {
        "tags": [
          "OpenAI Compatible TTS"
        ],
        "summary": "Download Audio File",
        "description": "Download a generated audio file from temp storage",
        "operationId": "download_audio_file_v1_download__filename__get",
        "parameters": [
          {
            "name": "filename",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Filename"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/models": {
      "get": {
        "tags": [
          "OpenAI Compatible TTS"
        ],
        "summary": "List Models",
        "description": "List all available models",
        "operationId": "list_models_v1_models_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/v1/models/{model}": {
      "get": {
        "tags": [
          "OpenAI Compatible TTS"
        ],
        "summary": "Retrieve Model",
        "description": "Retrieve a specific model",
        "operationId": "retrieve_model_v1_models__model__get",
        "parameters": [
          {
            "name": "model",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Model"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/audio/voices": {
      "get": {
        "tags": [
          "OpenAI Compatible TTS"
        ],
        "summary": "List Voices",
        "description": "List all available voices for text-to-speech.\n\nReturns `[{\"id\": ..., \"name\": ...}, ...]` by default so OpenAI-compatible\nclients (Open WebUI in particular, which does `voice['id']` directly and\nsilently falls back to a hardcoded 6-voice list otherwise) can render the\nfull voice list. Pass `?legacy=true` for the pre-0.3.x plain-string shape.",
        "operationId": "list_voices_v1_audio_voices_get",
        "parameters": [
          {
            "name": "legacy",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Legacy"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/audio/voices/combine": {
      "post": {
        "tags": [
          "OpenAI Compatible TTS"
        ],
        "summary": "Combine Voices",
        "description": "Combine multiple voices into a new voice and return the .pt file.\n\nArgs:\n    request: Either a string with voices separated by + (e.g. \"voice1+voice2\")\n            or a list of voice names to combine\n\nReturns:\n    FileResponse with the combined voice .pt file\n\nRaises:\n    HTTPException:\n        - 400: Invalid request (wrong number of voices, voice not found)\n        - 500: Server error (file system issues, combination failed)",
        "operationId": "combine_voices_v1_audio_voices_combine_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  }
                ],
                "title": "Request"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/dev/phonemize": {
      "post": {
        "tags": [
          "text processing"
        ],
        "summary": "Phonemize Text",
        "description": "Convert text to phonemes using Kokoro's quiet mode.\n\nArgs:\n    request: Request containing text and language\n\nReturns:\n    Phonemes and token IDs",
        "operationId": "phonemize_text_dev_phonemize_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PhonemeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhonemeResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/dev/generate_from_phonemes": {
      "post": {
        "tags": [
          "text processing"
        ],
        "summary": "Generate From Phonemes",
        "description": "Generate audio directly from phonemes using Kokoro's phoneme format",
        "operationId": "generate_from_phonemes_dev_generate_from_phonemes_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateFromPhonemesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/dev/captioned_speech": {
      "post": {
        "tags": [
          "text processing"
        ],
        "summary": "Create Captioned Speech",
        "description": "Generate audio with word-level timestamps using streaming approach",
        "operationId": "create_captioned_speech_dev_captioned_speech_post",
        "parameters": [
          {
            "name": "x-raw-response",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "title": "X-Raw-Response"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaptionedSpeechRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/dev/unload": {
      "post": {
        "tags": [
          "text processing"
        ],
        "summary": "Unload Model",
        "description": "Release the model from GPU VRAM without stopping the container.\n\nThe model reloads automatically on the next inference request.\nUseful for homelab deployments where GPU memory is shared across services.",
        "operationId": "unload_model_dev_unload_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/debug/threads": {
      "get": {
        "tags": [
          "debug"
        ],
        "summary": "Get Thread Info",
        "operationId": "get_thread_info_debug_threads_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/debug/storage": {
      "get": {
        "tags": [
          "debug"
        ],
        "summary": "Get Storage Info",
        "operationId": "get_storage_info_debug_storage_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/debug/system": {
      "get": {
        "tags": [
          "debug"
        ],
        "summary": "Get System Info",
        "operationId": "get_system_info_debug_system_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/debug/session_pools": {
      "get": {
        "tags": [
          "debug"
        ],
        "summary": "Get Session Pool Info",
        "description": "Get information about ONNX session pools.",
        "operationId": "get_session_pool_info_debug_session_pools_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/web/config": {
      "get": {
        "tags": [
          "Web Player"
        ],
        "summary": "Get Web Config",
        "description": "Get web player configuration including UVICORN_ROOT_PATH.",
        "operationId": "get_web_config_web_config_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/web/{filename}": {
      "get": {
        "tags": [
          "Web Player"
        ],
        "summary": "Serve Web File",
        "description": "Serve web player static files asynchronously.",
        "operationId": "serve_web_file_web__filename__get",
        "parameters": [
          {
            "name": "filename",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Filename"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Health Check",
        "description": "Health check endpoint",
        "operationId": "health_check_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/v1/test": {
      "get": {
        "summary": "Test Endpoint",
        "description": "Test endpoint to verify routing",
        "operationId": "test_endpoint_v1_test_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CaptionedSpeechRequest": {
        "properties": {
          "model": {
            "type": "string",
            "title": "Model",
            "description": "The model to use for generation. Supported models: tts-1, tts-1-hd, kokoro",
            "default": "kokoro"
          },
          "input": {
            "type": "string",
            "title": "Input",
            "description": "The text to generate audio for"
          },
          "voice": {
            "type": "string",
            "title": "Voice",
            "description": "The voice to use for generation. Can be a base voice or a combined voice name.",
            "default": "af_heart"
          },
          "response_format": {
            "type": "string",
            "enum": [
              "mp3",
              "opus",
              "aac",
              "flac",
              "wav",
              "pcm"
            ],
            "title": "Response Format",
            "description": "The format to return audio in. Supported formats: mp3, opus, flac, wav, pcm. PCM format returns raw 16-bit samples without headers. AAC is not currently supported.",
            "default": "mp3"
          },
          "speed": {
            "type": "number",
            "maximum": 4.0,
            "minimum": 0.25,
            "title": "Speed",
            "description": "The speed of the generated audio. Select a value from 0.25 to 4.0.",
            "default": 1.0
          },
          "stream": {
            "type": "boolean",
            "title": "Stream",
            "description": "If true (default), audio will be streamed as it's generated. Each chunk will be a complete sentence.",
            "default": true
          },
          "return_timestamps": {
            "type": "boolean",
            "title": "Return Timestamps",
            "description": "If true (default), returns word-level timestamps in the response",
            "default": true
          },
          "return_download_link": {
            "type": "boolean",
            "title": "Return Download Link",
            "description": "If true, returns a download link in X-Download-Path header after streaming completes",
            "default": false
          },
          "lang_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lang Code",
            "description": "Optional language code to use for text processing. If not provided, will use first letter of voice name."
          },
          "volume_multiplier": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Volume Multiplier",
            "description": "A volume multiplier to multiply the output audio by.",
            "default": 1.0
          },
          "normalization_options": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/NormalizationOptions"
              },
              {
                "type": "null"
              }
            ],
            "description": "Options for the normalization system",
            "default": {
              "normalize": true,
              "unit_normalization": false,
              "url_normalization": true,
              "email_normalization": true,
              "optional_pluralization_normalization": true,
              "phone_normalization": true,
              "replace_remaining_symbols": true
            }
          }
        },
        "type": "object",
        "required": [
          "input"
        ],
        "title": "CaptionedSpeechRequest",
        "description": "Request schema for captioned speech endpoint"
      },
      "GenerateFromPhonemesRequest": {
        "properties": {
          "phonemes": {
            "type": "string",
            "title": "Phonemes",
            "description": "Phoneme string to synthesize"
          },
          "voice": {
            "type": "string",
            "title": "Voice",
            "description": "Voice ID to use for generation"
          }
        },
        "type": "object",
        "required": [
          "phonemes",
          "voice"
        ],
        "title": "GenerateFromPhonemesRequest",
        "description": "Simple request for phoneme-to-speech generation"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "NormalizationOptions": {
        "properties": {
          "normalize": {
            "type": "boolean",
            "title": "Normalize",
            "description": "Normalizes input text to make it easier for the model to say",
            "default": true
          },
          "unit_normalization": {
            "type": "boolean",
            "title": "Unit Normalization",
            "description": "Transforms units like 10KB to 10 kilobytes",
            "default": false
          },
          "url_normalization": {
            "type": "boolean",
            "title": "Url Normalization",
            "description": "Changes urls so they can be properly pronounced by kokoro",
            "default": true
          },
          "email_normalization": {
            "type": "boolean",
            "title": "Email Normalization",
            "description": "Changes emails so they can be properly pronouced by kokoro",
            "default": true
          },
          "optional_pluralization_normalization": {
            "type": "boolean",
            "title": "Optional Pluralization Normalization",
            "description": "Replaces (s) with s so some words get pronounced correctly",
            "default": true
          },
          "phone_normalization": {
            "type": "boolean",
            "title": "Phone Normalization",
            "description": "Changes phone numbers so they can be properly pronouced by kokoro",
            "default": true
          },
          "replace_remaining_symbols": {
            "type": "boolean",
            "title": "Replace Remaining Symbols",
            "description": "Replaces the remaining symbols after normalization with their words",
            "default": true
          }
        },
        "type": "object",
        "title": "NormalizationOptions",
        "description": "Options for the normalization system"
      },
      "OpenAISpeechRequest": {
        "properties": {
          "model": {
            "type": "string",
            "title": "Model",
            "description": "The model to use for generation. Supported models: tts-1, tts-1-hd, kokoro",
            "default": "kokoro"
          },
          "input": {
            "type": "string",
            "title": "Input",
            "description": "The text to generate audio for"
          },
          "voice": {
            "type": "string",
            "title": "Voice",
            "description": "The voice to use for generation. Can be a base voice or a combined voice name.",
            "default": "af_heart"
          },
          "response_format": {
            "type": "string",
            "enum": [
              "mp3",
              "opus",
              "aac",
              "flac",
              "wav",
              "pcm"
            ],
            "title": "Response Format",
            "description": "The format to return audio in. Supported formats: mp3, opus, flac, wav, pcm. PCM format returns raw 16-bit samples without headers. AAC is not currently supported.",
            "default": "mp3"
          },
          "download_format": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "mp3",
                  "opus",
                  "aac",
                  "flac",
                  "wav",
                  "pcm"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Download Format",
            "description": "Optional different format for the final download. If not provided, uses response_format."
          },
          "speed": {
            "type": "number",
            "maximum": 4.0,
            "minimum": 0.25,
            "title": "Speed",
            "description": "The speed of the generated audio. Select a value from 0.25 to 4.0.",
            "default": 1.0
          },
          "stream": {
            "type": "boolean",
            "title": "Stream",
            "description": "If true (default), audio will be streamed as it's generated. Each chunk will be a complete sentence.",
            "default": true
          },
          "return_download_link": {
            "type": "boolean",
            "title": "Return Download Link",
            "description": "If true, returns a download link in X-Download-Path header after streaming completes",
            "default": false
          },
          "lang_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lang Code",
            "description": "Optional language code to use for text processing. If not provided, will use first letter of voice name."
          },
          "volume_multiplier": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Volume Multiplier",
            "description": "A volume multiplier to multiply the output audio by.",
            "default": 1.0
          },
          "normalization_options": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/NormalizationOptions"
              },
              {
                "type": "null"
              }
            ],
            "description": "Options for the normalization system",
            "default": {
              "normalize": true,
              "unit_normalization": false,
              "url_normalization": true,
              "email_normalization": true,
              "optional_pluralization_normalization": true,
              "phone_normalization": true,
              "replace_remaining_symbols": true
            }
          }
        },
        "type": "object",
        "required": [
          "input"
        ],
        "title": "OpenAISpeechRequest",
        "description": "Request schema for OpenAI-compatible speech endpoint"
      },
      "PhonemeRequest": {
        "properties": {
          "text": {
            "type": "string",
            "title": "Text"
          },
          "language": {
            "type": "string",
            "title": "Language",
            "default": "a"
          }
        },
        "type": "object",
        "required": [
          "text"
        ],
        "title": "PhonemeRequest"
      },
      "PhonemeResponse": {
        "properties": {
          "phonemes": {
            "type": "string",
            "title": "Phonemes"
          },
          "tokens": {
            "items": {
              "type": "integer"
            },
            "type": "array",
            "title": "Tokens"
          }
        },
        "type": "object",
        "required": [
          "phonemes",
          "tokens"
        ],
        "title": "PhonemeResponse"
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      }
    }
  }
}
