OpenAI TTS
This 'OpenAI TTS' node is really a door to any TTS server
- audio
The name is doing a lot of work. This node doesn't call OpenAI, needs no API key by default, and ships pointing at http://localhost:3001. What it actually is: a thin client that speaks OpenAI's /v1/audio/speech protocol to any endpoint that understands it - a real OpenAI-compatible provider if you want, or, more honestly, the author's own self-hosted Rust TTS server called Kokoros.
That's the case to understand before you install it. In the ComfyUI audio ecosystem - a layer bolted onto the image stack, full of heavy bespoke dependency piles - the usual way to get a voice is running Kokoro or Chatterbox natively inside ComfyUI via Python packages. This node takes the opposite route: the TTS model lives on a separate server, and the node just does HTTP. No model download, no VRAM for inference, no ONNX stack to babysit. The catch is you need a server to point it at, and the one this pack is tuned for is the author's own project.
How it works
The mechanism is plain, which is the point. The node POSTs a JSON payload to whatever url you set - model, input (your text), voice, response_format, plus a return_audio: True flag that's a Kokoros convention, not standard OpenAI - with a Bearer header when an api_key is set. A non-200 response raises with the status code and body, so a wrong URL or model name is an obvious error, not silent garbage.
On success it decodes the audio and hands you a standard ComfyUI AUDIO dictionary. Worth knowing how it reads the response: if the server returns JSON it looks for either a file_path (and then opens that file from disk - on the machine running ComfyUI, so the file has to exist there) or a base64 audio field; anything else is treated as raw bytes. Then torchaudio.load turns it into a waveform tensor, a batch dimension gets added, and you're done.
The inputs that matter
Six required fields, all plain strings. A beginner sets four of them:
- text - what to say. Default
"Hello world". - url - the endpoint. Default
http://localhost:3001/v1/audio/speech, i.e. a local Kokoros. - model - the identifier your endpoint expects.
default_tts_modelis Kokoros's; the real OpenAI API wants names liketts-1. - voice - a voice ID. The default
af_skyis a Kokoro voice name (Kokoro's preset bank is real and well-covered in the KB). Here's the genuinely fun bit: on the Kokoros endpoint you can pass comma-separated IDs with weights, like"af_sky,af_nicole.5", and it blends voices - a feature the official OpenAI API doesn't offer and will just choke on. - api_key - leave blank for self-hosted, fill it for a paid provider.
- response_format -
mp3orwavon Kokoros. Other formats are only a maybe on other endpoints.
The single audio output is the dict with waveform (tensor, normalized to [-1, 1]) and sample_rate. Wire it into the built-in PreviewAudio node or anything else that accepts an AUDIO input.
Installing it
ComfyUI Manager: search ComfyUI-TTS-OAI, install, restart. Or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/DrMWeigand/ComfyUI-TTS-OAI
Then make sure the deps are present - torch torchaudio pydub numpy requests (Manager usually handles this via the pyproject, but if the node shows up red, that import line is why). The README insists you need FFmpeg for pydub. In practice the decode path runs through torchaudio, and pydub is imported but barely used - so if you only ever ask for wav you may dodge FFmpeg entirely; if mp3 decoding fails, that's the thing to install.
Where people get burned
- It's not actually about OpenAI. Point it at the real API and the extra
return_audiofield and Kokoro-specific voice syntax are at best ignored, at worst errors. This node's happy place is the author's own server, and that server has effectively zero community footprint - nobody on the usual boards is talking about Kokoros. Treat this as glue for your TTS endpoint, not a discovery tool. - mp3/wav only. Ask for something else on Kokoros and the decode step throws.
- The
file_pathtrust issue. A server response can tell the node to open an arbitrary file path. Fine for your own endpoint, a genuine footgun if you ever point this at something untrusted. - Never paste a paid
api_keyinto a shared workflow. The field defaults to empty and stays in the saved JSON; keep it that way in anything you export.
The verdict: if you already run a voice server behind an OpenAI-compatible API, this is a tidy five-minute hookup. If you just want a voice in ComfyUI today, run Kokoro or Chatterbox locally instead - the API route only pays off when the server already exists.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | Hello world | — |
| model | STRING | default_tts_model | — |
| voice | STRING | af_sky | — |
| api_key | STRING | — | |
| url | STRING | http://localhost:3001/v1/audio/speech | — |
| response_format | STRING | mp3 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |