{"openapi":"3.1.0","info":{"title":"FishSpeech Open API","version":"1.0.0","description":"Current public Open API contract. Bearer API tokens are required for Open API operations."},"servers":[{"url":"/api/open/v1","description":"Canonical Open API v1 base path"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token"}},"schemas":{"ErrorResponse":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"}},"additionalProperties":true},"ProfileResponse":{"type":"object","required":["user_id","api_quota_remaining","tier","credits"],"properties":{"user_id":{"type":"string"},"api_quota_remaining":{"type":"integer"},"tier":{"type":"string"},"credits":{"type":"integer"}}},"CachedTtsResponse":{"type":"object","required":["success","audio_url","format","characters_used","credits_used","quota_remaining","expires_at"],"properties":{"success":{"type":"boolean"},"audio_url":{"type":"string","format":"uri"},"format":{"type":"string"},"characters_used":{"type":"integer"},"credits_used":{"type":"integer"},"quota_remaining":{"type":"integer"},"expires_at":{"type":"string","format":"date-time"}}},"TtsJobResponse":{"type":"object","required":["task","record","requestId"],"properties":{"task":{"type":"object","additionalProperties":true},"record":{"type":"object","additionalProperties":true},"requestId":{"type":"string"},"quotaRemaining":{"type":"integer"},"creditsUsed":{"type":"integer"}}},"SpeechToTextResponse":{"type":"object","required":["text","duration","segments","credits_used","quota_remaining"],"properties":{"text":{"type":"string"},"duration":{"type":"number"},"segments":{"type":"array","items":{"type":"object","additionalProperties":true}},"credits_used":{"type":"integer"},"quota_remaining":{"type":"integer"}}},"LipSyncEnvelope":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"},"data":{"type":"object","additionalProperties":true}}},"ModelListResponse":{"type":"object","required":["total","page","pageSize","totalPages","items"],"properties":{"total":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"totalPages":{"type":"integer"},"items":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}},"paths":{"/profile":{"get":{"summary":"Get Open API profile and quota","operationId":"getOpenProfile","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Update Open API profile settings","operationId":"updateOpenProfile","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/speech/tts":{"post":{"summary":"Generate speech from text","operationId":"createOpenTts","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string"},"voiceId":{"type":"string","description":"Preferred voice id field for new clients"},"reference_id":{"type":"string","description":"Legacy alias for voiceId"},"modelId":{"type":"string","description":"Legacy alias for voiceId"},"format":{"type":"string","enum":["mp3","wav"]},"cache":{"type":"boolean"}},"additionalProperties":true}}}},"responses":{"200":{"description":"Binary audio for cache=false or JSON metadata for cache=true","content":{"audio/mpeg":{"schema":{"type":"string","format":"binary"}},"audio/wav":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"$ref":"#/components/schemas/CachedTtsResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/speech/tts/jobs":{"post":{"summary":"Create async TTS task","operationId":"createOpenTtsJob","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","voiceId"],"properties":{"text":{"type":"string"},"voiceId":{"type":"string"},"engineModelId":{"type":"string"},"format":{"type":"string","enum":["mp3","wav"]}},"additionalProperties":true}}}},"responses":{"202":{"description":"Task accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TtsJobResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/speech/tts/jobs/{taskId}":{"get":{"summary":"Get async TTS task","operationId":"getOpenTtsJob","parameters":[{"name":"taskId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TtsJobResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/speech/transcriptions":{"post":{"summary":"Transcribe speech to text","operationId":"createOpenSpeechTranscription","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpeechToTextResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/voices":{"get":{"summary":"List available voices","operationId":"listOpenVoices","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelListResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Create voice model","operationId":"createOpenVoice","responses":{"200":{"description":"Voice model creation response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/voices/{voiceId}":{"delete":{"summary":"Delete voice model","operationId":"deleteOpenVoice","parameters":[{"name":"voiceId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Voice model deletion response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/media/lip-sync/jobs":{"post":{"summary":"Create lip-sync job","operationId":"createOpenLipSyncJob","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LipSyncEnvelope"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"summary":"List lip-sync jobs","operationId":"listOpenLipSyncJobs","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LipSyncEnvelope"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/media/lip-sync/jobs/{jobId}":{"get":{"summary":"Get lip-sync job","operationId":"getOpenLipSyncJob","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LipSyncEnvelope"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Insufficient API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"x-legacy-aliases":{"POST /api/open/create-model":"POST /api/open/v1/voices","POST /api/open/delete-model":"DELETE /api/open/v1/voices/{voiceId}","POST /api/open/list-models":"GET /api/open/v1/voices","POST /api/open/lip-sync/create":"POST /api/open/v1/media/lip-sync/jobs","GET /api/open/lip-sync/list":"GET /api/open/v1/media/lip-sync/jobs","GET /api/open/lip-sync/query":"GET /api/open/v1/media/lip-sync/jobs/{jobId}"}}