{"openapi":"3.1.0","info":{"title":"Sarj TTS API","description":"Production speech synthesis API serving the single `sarj-tts` model. The speech endpoint uses an OpenAI SDK-compatible request and response shape.","version":"0.3.0"},"paths":{"/v1/audio/speech":{"post":{"summary":"Create Speech","description":"Generate speech from text.","operationId":"create_speech_v1_audio_speech_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpeechRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/audio/speech/clone":{"post":{"summary":"Create Speech Clone","description":"One-shot voice cloning. Upload reference audio + text to synthesize.","operationId":"create_speech_clone_v1_audio_speech_clone_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_speech_clone_v1_audio_speech_clone_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/voices":{"get":{"summary":"List available voices","description":"Authoritative runtime voice discovery. Entries with `type=builtin` are the deployed Sarj voice catalog; the response also identifies design modes, compatible presets, and saved clone profiles.","operationId":"list_voices_v1_voices_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceListResponse"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/voices/profiles":{"post":{"summary":"Create Profile","operationId":"create_profile_v1_voices_profiles_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_profile_v1_voices_profiles_post"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/voices/profiles/{profile_id}":{"get":{"summary":"Get Profile","operationId":"get_profile_v1_voices_profiles__profile_id__get","parameters":[{"name":"profile_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-zA-Z0-9_-]{1,64}$","title":"Profile Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"BearerAuth":[]}]},"delete":{"summary":"Delete Profile","operationId":"delete_profile_v1_voices_profiles__profile_id__delete","parameters":[{"name":"profile_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-zA-Z0-9_-]{1,64}$","title":"Profile Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"BearerAuth":[]}]},"patch":{"summary":"Update Profile","operationId":"update_profile_v1_voices_profiles__profile_id__patch","parameters":[{"name":"profile_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-zA-Z0-9_-]{1,64}$","title":"Profile Id"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_update_profile_v1_voices_profiles__profile_id__patch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/models":{"get":{"summary":"List Sarj TTS models","description":"Return the single model served by this API.","operationId":"list_models_v1_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelListResponse"}}}}}}},"/v1/models/{model_id}":{"get":{"summary":"Retrieve Sarj TTS","description":"Retrieve canonical metadata for `sarj-tts` or a historical request alias.","operationId":"get_model_v1_models__model_id__get","parameters":[{"name":"model_id","in":"path","required":true,"schema":{"type":"string","title":"Model Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelObject"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/audio/script":{"post":{"summary":"Create Script Audio","description":"Synthesize multi-speaker script with voice resolution and mixing.\n\nReturns either:\n- single_track: Binary audio with metadata headers\n- multi_track: JSON with per-speaker tracks and segment timestamps","operationId":"create_script_audio_v1_audio_script_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScriptRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"BearerAuth":[]}]}},"/health":{"get":{"summary":"Health","description":"Readiness check. Returns 503 while model is loading, 200 when ready.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/metrics":{"get":{"summary":"Metrics","description":"Request metrics and current memory usage.","operationId":"metrics_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"Body_create_profile_v1_voices_profiles_post":{"properties":{"profile_id":{"type":"string","pattern":"^[a-zA-Z0-9_-]{1,64}$","title":"Profile Id","description":"Unique identifier. Alphanumeric, dashes, underscores only."},"ref_audio":{"type":"string","contentMediaType":"application/octet-stream","title":"Ref Audio"},"ref_text":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}],"title":"Ref Text"},"overwrite":{"type":"boolean","title":"Overwrite","default":false}},"type":"object","required":["profile_id","ref_audio"],"title":"Body_create_profile_v1_voices_profiles_post"},"Body_create_speech_clone_v1_audio_speech_clone_post":{"properties":{"text":{"type":"string","maxLength":50000,"minLength":1,"title":"Text"},"ref_audio":{"type":"string","contentMediaType":"application/octet-stream","title":"Ref Audio"},"ref_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref Text"},"response_format":{"type":"string","enum":["mp3","opus","aac","flac","wav","pcm"],"title":"Response Format","default":"wav"},"stream":{"type":"boolean","title":"Stream","default":false},"speed":{"type":"number","maximum":4.0,"minimum":0.25,"title":"Speed","default":1.0},"num_step":{"anyOf":[{"type":"integer","maximum":64.0,"minimum":1.0},{"type":"null"}],"title":"Num Step"},"guidance_scale":{"anyOf":[{"type":"number","maximum":10.0,"minimum":0.0},{"type":"null"}],"title":"Guidance Scale"},"denoise":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Denoise"},"t_shift":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"T Shift"},"position_temperature":{"anyOf":[{"type":"number","maximum":10.0,"minimum":0.0},{"type":"null"}],"title":"Position Temperature"},"class_temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Class Temperature"},"duration":{"anyOf":[{"type":"number","maximum":60.0,"minimum":0.1},{"type":"null"}],"title":"Duration"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language","description":"Language code (e.g., 'en', 'vi', 'zh') for multilingual pronunciation"},"layer_penalty_factor":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Layer Penalty Factor"},"preprocess_prompt":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Preprocess Prompt"},"postprocess_output":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Postprocess Output"},"audio_chunk_duration":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Audio Chunk Duration"},"audio_chunk_threshold":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Audio Chunk Threshold"},"request_timeout_s":{"anyOf":[{"type":"integer","maximum":600.0,"minimum":1.0},{"type":"null"}],"title":"Request Timeout S"}},"type":"object","required":["text","ref_audio"],"title":"Body_create_speech_clone_v1_audio_speech_clone_post"},"Body_update_profile_v1_voices_profiles__profile_id__patch":{"properties":{"ref_audio":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Ref Audio"},"ref_text":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}],"title":"Ref Text"}},"type":"object","title":"Body_update_profile_v1_voices_profiles__profile_id__patch"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ModelListResponse":{"properties":{"object":{"type":"string","const":"list","title":"Object","default":"list"},"data":{"items":{"$ref":"#/components/schemas/ModelObject"},"type":"array","title":"Data"}},"type":"object","required":["data"],"title":"ModelListResponse"},"ModelObject":{"properties":{"id":{"type":"string","const":"sarj-tts","title":"Id","default":"sarj-tts"},"object":{"type":"string","const":"model","title":"Object","default":"model"},"created":{"type":"integer","minimum":0.0,"title":"Created","default":1791348449},"owned_by":{"type":"string","const":"sarj-ai","title":"Owned By","default":"sarj-ai"},"permission":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Permission"},"root":{"type":"string","const":"sarj-tts","title":"Root","default":"sarj-tts"},"parent":{"type":"null","title":"Parent"}},"type":"object","title":"ModelObject","description":"Stable model metadata returned by the discovery endpoints."},"ScriptRequest":{"properties":{"script":{"items":{"$ref":"#/components/schemas/ScriptSegment"},"type":"array","maxItems":100,"minItems":1,"title":"Script"},"default_voice":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Voice"},"speed":{"type":"number","maximum":4.0,"minimum":0.25,"title":"Speed","default":1.0},"response_format":{"type":"string","enum":["mp3","opus","aac","flac","wav","pcm"],"title":"Response Format","default":"wav"},"output_format":{"type":"string","enum":["single_track","multi_track"],"title":"Output Format","default":"single_track"},"pause_between_speakers":{"type":"number","maximum":5.0,"minimum":0.0,"title":"Pause Between Speakers","default":0.5},"on_error":{"type":"string","enum":["abort","skip"],"title":"On Error","default":"abort"}},"type":"object","required":["script"],"title":"ScriptRequest","description":"Request body for /v1/audio/script endpoint."},"ScriptSegment":{"properties":{"speaker":{"type":"string","maxLength":64,"minLength":1,"title":"Speaker"},"text":{"type":"string","maxLength":10000,"minLength":1,"title":"Text"},"voice":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice"},"speed":{"anyOf":[{"type":"number","maximum":4.0,"minimum":0.25},{"type":"null"}],"title":"Speed"}},"type":"object","required":["speaker","text"],"title":"ScriptSegment","description":"Single segment in a multi-speaker script."},"SpeechRequest":{"properties":{"model":{"type":"string","const":"sarj-tts","title":"Model","description":"Sarj TTS model identifier. This API serves only `sarj-tts`.","default":"sarj-tts"},"input":{"type":"string","maxLength":50000,"minLength":1,"title":"Input"},"voice":{"anyOf":[{"type":"string"},{"$ref":"#/components/schemas/VoiceObject"}],"title":"Voice","description":"Voice ID from `GET /v1/voices`, or an object containing that ID.","default":"auto","examples":["ars_male","ars_fares","ars_female","ars_ibrahim_studio_male"]},"speaker":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Speaker"},"instructions":{"anyOf":[{"type":"string","maxLength":4096},{"type":"null"}],"title":"Instructions"},"response_format":{"type":"string","enum":["mp3","opus","aac","flac","wav","pcm"],"title":"Response Format","default":"mp3"},"speed":{"type":"number","maximum":4.0,"minimum":0.25,"title":"Speed","default":1.0},"stream_format":{"anyOf":[{"type":"string","enum":["sse","audio"]},{"type":"null"}],"title":"Stream Format"},"stream":{"type":"boolean","title":"Stream","default":false},"num_step":{"anyOf":[{"type":"integer","maximum":64.0,"minimum":1.0},{"type":"null"}],"title":"Num Step"},"guidance_scale":{"anyOf":[{"type":"number","maximum":10.0,"minimum":0.0},{"type":"null"}],"title":"Guidance Scale"},"denoise":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Denoise"},"t_shift":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"T Shift"},"position_temperature":{"anyOf":[{"type":"number","maximum":10.0,"minimum":0.0},{"type":"null"}],"title":"Position Temperature"},"class_temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Class Temperature"},"duration":{"anyOf":[{"type":"number","maximum":60.0,"minimum":0.1},{"type":"null"}],"title":"Duration"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language","description":"Language code (e.g., 'en', 'vi', 'zh') for multilingual pronunciation"},"layer_penalty_factor":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Layer Penalty Factor"},"preprocess_prompt":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Preprocess Prompt"},"postprocess_output":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Postprocess Output"},"audio_chunk_duration":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Audio Chunk Duration"},"audio_chunk_threshold":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Audio Chunk Threshold"},"request_timeout_s":{"anyOf":[{"type":"integer","maximum":600.0,"minimum":1.0},{"type":"null"}],"title":"Request Timeout S"}},"type":"object","required":["input"],"title":"SpeechRequest","description":"Sarj TTS request body with an OpenAI SDK-compatible shape."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VoiceEntry":{"properties":{"id":{"type":"string","minLength":1,"title":"Id"},"type":{"type":"string","minLength":1,"title":"Type"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"language_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language Name"},"dialect":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dialect"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"profile_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Id"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"ref_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref Text"},"generation_defaults":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Generation Defaults"}},"type":"object","required":["id","type"],"title":"VoiceEntry"},"VoiceListResponse":{"properties":{"voices":{"items":{"$ref":"#/components/schemas/VoiceEntry"},"type":"array","title":"Voices"},"design_attributes":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object","title":"Design Attributes"},"languages":{"additionalProperties":{"type":"string"},"type":"object","title":"Languages"},"total":{"type":"integer","minimum":0.0,"title":"Total"}},"type":"object","required":["voices","design_attributes","languages","total"],"title":"VoiceListResponse"},"VoiceObject":{"properties":{"id":{"type":"string","maxLength":128,"minLength":1,"title":"Id"}},"type":"object","required":["id"],"title":"VoiceObject","description":"OpenAI custom voice object: {\"id\": \"...\"}."},"VoiceProfileResponse":{"properties":{"profile_id":{"type":"string","pattern":"^[a-zA-Z0-9_-]{1,64}$","title":"Profile Id"},"name":{"type":"string","minLength":1,"title":"Name"},"ref_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref Text"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["profile_id","name","created_at"],"title":"VoiceProfileResponse"}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API key"}}}}