export type TTSModelID = 'sonic-3.5' | 'sonic-3' | 'sonic-latest'; export type VoiceId = string; export type TTSRequestVoiceSpecifier = {mode: 'id', id: VoiceId}; export type RawEncoding = 'pcm_f32le' | 'pcm_s16le' | 'pcm_mulaw' | 'pcm_alaw'; export type SSEOutputFormat = {container: 'raw', encoding: RawEncoding, sample_rate: 8000 | 16000 | 22050 | 24000 | 44100 | 48000}; export type SupportedLanguage = 'en' | 'fr' | 'de' | 'es' | 'pt' | 'zh' | 'ja' | 'hi' | 'it' | 'ko' | 'nl' | 'pl' | 'ru' | 'sv' | 'tr' | 'tl' | 'bg' | 'ro' | 'ar' | 'cs' | 'el' | 'fi' | 'hr' | 'ms' | 'sk' | 'da' | 'ta' | 'uk' | 'hu' | 'no' | 'vi' | 'bn' | 'th' | 'he' | 'ka' | 'id' | 'te' | 'gu' | 'kn' | 'ml' | 'mr' | 'pa'; export type Emotion = 'neutral' | 'happy' | 'excited' | 'enthusiastic' | 'elated' | 'euphoric' | 'triumphant' | 'amazed' | 'surprised' | 'flirtatious' | 'curious' | 'content' | 'peaceful' | 'serene' | 'calm' | 'grateful' | 'affectionate' | 'trust' | 'sympathetic' | 'anticipation' | 'mysterious' | 'angry' | 'mad' | 'outraged' | 'frustrated' | 'agitated' | 'threatened' | 'disgusted' | 'contempt' | 'envious' | 'sarcastic' | 'ironic' | 'sad' | 'dejected' | 'melancholic' | 'disappointed' | 'hurt' | 'guilty' | 'bored' | 'tired' | 'rejected' | 'nostalgic' | 'wistful' | 'apologetic' | 'hesitant' | 'insecure' | 'confused' | 'resigned' | 'anxious' | 'panicked' | 'alarmed' | 'scared' | 'proud' | 'confident' | 'distant' | 'skeptical' | 'contemplative' | 'determined'; export type GenerationConfig = {volume?: number | undefined, speed?: number | undefined, emotion?: Emotion | undefined}; export type ModelSpeed = 'slow' | 'normal' | 'fast'; export type SSEContextID = string | null; export type TTSSSERequest = {model_id: TTSModelID, transcript: string, voice: TTSRequestVoiceSpecifier, output_format: SSEOutputFormat, language?: SupportedLanguage | undefined, add_timestamps?: (boolean | null) | undefined, add_phoneme_timestamps?: (boolean | null) | undefined, use_normalized_timestamps?: (boolean | null) | undefined, pronunciation_dict_id?: (string | null) | undefined, generation_config?: GenerationConfig | undefined, speed?: ModelSpeed | undefined, context_id?: SSEContextID | undefined}; export type CreateApiTtsSseArgs = {'Cartesia-Version': '2026-03-01', body: TTSSSERequest}; export type CreateApiTtsSseOptions = {baseUrl?: string | undefined, APIKeyAuth?: string | undefined, fetch?: typeof fetch | undefined}; /** * Text-to-Speech (SSE) * * POST /tts/sse * * Also accepts auth: AccessTokenAuth */ export const createApiTtsSse = async (args: CreateApiTtsSseArgs, options?: CreateApiTtsSseOptions) => { const {baseUrl = "https://api.cartesia.ai", fetch: fetchFn = fetch, APIKeyAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "text/event-stream") if (args['Cartesia-Version'] != null) headers.set("Cartesia-Version", String(args['Cartesia-Version'])) if (APIKeyAuth !== undefined) headers.set('authorization', `Bearer ${APIKeyAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/tts/sse${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return res.text() };