Grok STT · Speech to Text
Two Hours of Audio Transcribed for About a Quarter
- audio_url
- text
- task id
Speech-to-text is the least glamorous job in this whole pack and possibly the best value in it. xAI's Grok STT is billed at $0.0000333334 per second of audio - read it as two-tenths of a cent a minute, or roughly twelve cents an hour. The maximum input is two hours, which costs about a quarter.
Set against the TTS and music nodes on either side of it, that's noise. If you've ever priced a two-hour interview through a hosted transcription service, you know the difference.
Why it's in a ComfyUI pack
Transcription is the input side of an audio workflow, and the KB's read on this corner of the ecosystem is that audio tooling arrived late and mostly to serve video - the models are genuinely good, but they live in bespoke packs rather than the centre of the ecosystem. A transcription node earns its place in that picture because it turns a mouth into a string: interview, podcast, voice memo, or your own generated dialogue, converted to text you can feed into a prompt, a Chat node, or a text file.
It's a normal ComfyUI flow. Load Audio → Grok STT → text into whatever wants a string.
How it works
audio_url is an AUDIO socket. The pack encodes whatever it gets to 16-bit PCM WAV, uploads it, and hands back the transcript as a STRING on the text output, with a task id beside it for console lookups or support. The model's own documentation mentions word-level timings and a detected language - worth knowing they exist upstream, but what this node exposes is one text socket, so don't go hunting for separate timing outputs in the graph.
Outputs: text (STRING) and task id. Neither saves anything, so put something downstream - a Show Text, a Preview Any, or a prompt input on an image or video node.
The inputs worth setting
- audio_url - the audio itself. Accepts an uploaded MP3 or WAV, or a public URL to a common audio or video format, and handles anything from 1 second to 2 hours.
- language - default
model default, which means detect it. Twenty-five languages are listed: ar, cs, da, nl, en, fil, fr, de, hi, id, it, ja, ko, mk, ms, fa, pl, pt, ro, ru, es, sv, th, tr, vi. Setting it explicitly matters for one reason below. - text_normalization - writes spoken numbers, prices, dates and units as digits. It requires
language. This is the trap on this node: turn it on with the language left on detect and the request is invalid, not silently ignored. - keyterms - up to 100 names and terms the transcript should spell your way. It's JSON, and the shape is a list of objects with a
termkey, because it's the model's own schema passed through:
Type a comma-separated list instead and it won't parse. This is the single most useful field here for names, brands, jargon and product spellings.[{"term": "SpicyAPI"}, {"term": "ComfyUI"}, {"term": "LoRA"}] - filler_words - keeps the ums and uhs. Off by default, which is the right default for subtitles and the wrong one if you're mining a transcript for speech patterns.
- multichannel - transcribes each channel separately, one line per channel. Turn it on when speakers are genuinely on separate tracks, not to fake diarisation; on a mixed-down stereo file it will not separate anyone.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/spicyapi-ai/comfyui-spicyapi
Restart ComfyUI, then Settings > SpicyAPI and paste a key from spicyapi.ai/console/keys; restart once so the node dictionary is rebuilt from your account. On a headless machine, SPICY_API_KEY in the environment is tidier.
The install is the boring kind: dependencies = [] in the project file, and it uses aiohttp, torch, Pillow and PyAV, all of which ComfyUI already ships. No model downloads, no pip step, no risk of your transcription node breaking someone else's transformers pin. Python 3.10+, V3 node API, tested at ComfyUI 0.39.
Where people get burned
Two hours is the ceiling - longer files need splitting, and the pack caps audio at 90 MiB (the input audio is longer than the 90 MiB upload limit allows), so an unusually long uncompressed WAV may need re-encoding to MP3 first. Every run is billed (at this rate, who cares, but the rule is the rule), and seeds ship fixed so a duplicate queue reuses the cached result instead of paying twice. Cancelling a run ends your wait but not the job: it completes on SpicyAPI and is charged if it succeeds.
The errors you'll meet: No SpicyAPI key is set, 40310 for an unverified email, 40004 when a chosen combination has no deployment, and anything ending in request_id ... - quote that id to support. If transcription matters to your output quality, spend five minutes on keyterms before you spend an hour blaming the model for spelling your product name wrong.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| audio_url | AUDIO | Audio to transcribe: an uploaded MP3 or WAV, or a public URL to a common audio or video format. 1 second to 2 hours. | |
| language | COMBO | model default | Spoken language. Leave empty to detect it; required when text_normalization is on. |
| text_normalization | BOOLEAN | false | Write spoken numbers, prices, dates and units in digits. Needs language. |
| keyterms | STRING | Names and terms to spell the way you list them, up to 100. JSON. A list of objects with "term". | |
| filler_words | BOOLEAN | false | Keep filler words such as um and uh in the transcript. |
| multichannel | BOOLEAN | false | Transcribe each channel separately, one line per channel. Turn on when speakers are on separate channels. |
| seed | INT | 00–2147483647 | This model takes no seed, so the number is never sent. Changing it makes ComfyUI run the node again: set 'control after generate' to randomize for a new result on every run; every run is billed. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |
| task id | STRING | The SpicyAPI task id, for the console logs or support. |