Cartesia Sonic-3 TTS
Cartesia Sonic-3 TTS in ComfyUI
- upload_to_tmpfiles
- file_path
- bytes
- url
- audio
You know the moment a generated video is almost done and then you have to go dubbing it in a separate tool? This node is the shortcut for that. Cartesia Sonic-3 TTS drops text-to-speech straight into your ComfyUI graph, calling Cartesia's cloud API and handing you back a finished audio file, a URL, and a proper AUDIO tensor you can wire into the rest of your workflow. If you're building talking-avatar or narration pipelines - the README's own example feeds the audio URL straight into HeyGen's /video/generate - this is the missing step between "text" and "a voice saying it."
The name is honest about one thing: it's a thin wrapper. The whole pack is a single node, and it doesn't download any model to your machine. It does a synchronous POST to https://api.cartesia.ai/tts/bytes with your API key in the X-API-Key header, gets the raw audio back, writes it to a temp file, and builds a PyTorch AUDIO tensor from it via soundfile. The model ("sonic-3" by default) runs entirely on Cartesia's servers - Cartesia launched Sonic back in 2024 on the back of its founders' state-space-model work, and its whole pitch is low-latency, lifelike speech. That latency matters here, because the call blocks: your whole graph waits up to 120 seconds while it generates.
What you actually set
Three required inputs and a handful of options, and honestly the required ones are the whole node:
- api_key - your Cartesia API key from their dashboard. No key, no output; there's no local fallback.
- transcript - the text to speak. Multiline, so paste a paragraph without squinting.
- voice_id - the ID of a voice from Cartesia's voice library. This is the fiddly bit: the node does not browse voices for you, so grab an ID from Cartesia's playground or API first and paste it in.
The options are worth a quick pass: container (wav/mp3/raw), encoding (default pcm_f32le), sample_rate (44100, range 8000–48000), gen_speed (0.6–1.5) and gen_volume (0.5–2.0) for performance tweaks, and save_basename for the temp file prefix. upload_to_tmpfiles is the one to know about: flip it on and the node tries to push the audio to tmpfiles.org and hand you a public URL - handy for handing off to external APIs like HeyGen - but it's explicitly "best-effort," and falls back to a file:// path if the upload fails.
The outputs
Four of them, and you'll mostly use one: file_path (absolute path to the saved file), bytes (raw audio bytes), url (file:// or tmpfiles link), and audio - a proper AUDIO tensor that plugs into other ComfyUI audio nodes. If you're staying inside ComfyUI, wire audio; if you're passing off to an external API, use url or bytes.
Install
The standard dance, and it's light:
cd ComfyUI/custom_nodes
git clone https://github.com/PauldeLavallaz/ComfyUI-CartesiaTTS
Restart ComfyUI and the node shows up under the "Cartesia" category. Or use ComfyUI Manager and search "ComfyUI-CartesiaTTS". The declared dependency is just requests, which you already have. One quirk worth knowing: the code also imports soundfile and torch - both ship with a normal ComfyUI install, so it works, but if you run a stripped environment and get an import error, that's the culprit.
Where people get burned
- It's paid and it's online. Every generation costs API credits and sends your transcript to Cartesia. Great for avatars and dubbing; wrong tool if you want free, private, local TTS - for that you're in local-model territory (the community's go-tos are things like VibeVoice) and this node isn't it.
- The block. The synchronous call freezes the graph mid-run. Long transcripts can sit there for a while, so don't treat it like a local node that streams.
- Errors surface as a plain
RuntimeErrorwith the HTTP status and body. A 401 means your key is wrong; a 4xx with a validation message usually means a badvoice_idor an unsupportedcontainer(wav/mp3/raw only). Read the message, not the node. - Don't chase the
upload_to_tmpfileslink as a permanent host. tmpfiles.org files expire; treat it as a handoff, not storage.
It's a small node with a single job, and it does that job without fuss. If your ComfyUI pipeline needs to talk, this is the easiest way to make it.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| api_key | STRING | — | |
| transcript | STRING | — | |
| voice_id | STRING | — | |
| model_idopt | STRING | sonic-3 | — |
| containeropt | STRING | wav | — |
| encodingopt | STRING | pcm_f32le | — |
| sample_rateopt | INT | 441008000–48000 | — |
| gen_speedopt | FLOAT | 1.000.6–1.5 | — |
| gen_volumeopt | FLOAT | 1.000.5–2 | — |
| save_basenameopt | STRING | cartesia_audio | — |
| upload_to_tmpfilesopt | BOOL | false | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| file_path | STRING | — |
| bytes | BYTES | — |
| url | STRING | — |
| audio | AUDIO | — |