- Binary WebSocket frames containing raw audio.
- JSON WebSocket messages containing base64-encoded audio.
custom-tts
API compatibility: websocket_v1
Custom TTS is configured from credentials and assistant voice output settings. You do not need to write a new Rapida transformer when the provider protocol can be described with the DSL on this page.
Setup flow
1
Confirm the provider protocol
Custom TTS supports
websocket_v1. Your provider must accept a WebSocket connection and return audio or status messages over that same connection.2
Create the Custom TTS credential
Open Credentials or Integrations > Models, choose Custom TTS, and create a credential with
apiCompatibility, baseUrl, and any required headers.3
Select Custom TTS for voice output
Open the assistant or deployment voice settings, go to Voice Output, and select Custom TTS as the text-to-speech provider.
4
Set the output audio format
Choose the audio encoding and sample rate returned by your provider.Rapida interprets provider audio using these values, then resamples it to Rapida’s internal audio format when needed.
5
Write the DSL configuration
Fill
speak.query_params, speak.request_rules, and speak.response_rules.Query parameters build the provider WebSocket URL. Request rules map Rapida text lifecycle packets to outbound provider frames. Response rules map provider frames to audio, done, or error events.6
Test speech and interruption
Run a test conversation. Confirm that audio plays, done events end the response cleanly, and interruption stops any queued provider audio.
Credential fields
Create one credential for the external TTS provider.
The runtime also accepts snake case credential keys:
api_compatibility and base_url.
Assistant TTS arguments
These fields are configured on the assistant or deployment voice output provider. The UI stores them with the provider metadata, and the runtime reads the option keys shown below.The UI exposes the audio and DSL fields.
speak.voice.id, speak.model, and speak.language are optional metadata keys for API-driven or imported configurations. If your provider needs fixed voice, model, or language values and those fields are not available in your UI, put the values directly in query params or request rules.When you work with raw assistant metadata, use the unprefixed custom TTS option keys, such as
speak.request_rules. The UI may preserve other speaker-level settings under speaker.*, but the custom TTS DSL fields are the speak.* keys listed above.DSL overview
Custom TTS has three DSL sections.
The DSL is intentionally small. It does not run JavaScript, call functions, perform regex matching, concatenate strings, perform compound conditions, read environment variables, or compute authentication signatures.
Query parameters
Usespeak.query_params when your provider expects configuration in the WebSocket URL.
Query variable reference
Query parameter expressions can use$var to read these variables.
Query parameter rules
speak.query_paramsmust be a JSON object.- The object must be flat. A query parameter value cannot be a nested object or array unless that object is a supported DSL expression.
- Each rendered value must be a primitive supported by the UI validator: string, number, or boolean.
- Existing query parameters in
baseUrlare preserved unlessspeak.query_paramsrenders the same key. - A key that starts with
$is treated as an unsupported operator and is rejected. textis not a supported query parameter variable. Usepacket.textin request rules.
Request rules
speak.request_rules is an ordered JSON array. Each rule has a when block and a send block.
Request packet reference
Request frame reference
Every matching request rule for a packet is sent in order. This lets one
text, done, or interrupt packet produce more than one provider message when required.
Request scope
Request rules use$path to read from the request scope.
For text:
done and interrupt, packet.text is present but may be empty:
Request path reference
One-shot synthesis example
Use this when the provider synthesizes each text packet immediately.Text, done, and interrupt example
Use this when the provider expects text payloads, an explicit final message, and an explicit cancel message.Response rules
speak.response_rules is an ordered JSON array. Each provider WebSocket response is parsed into a binary, json, or text frame, then the first matching response rule is evaluated. Custom TTS response rules support binary and json; text responses are ignored unless you change the provider to send JSON status messages.
Response frame parsing
Response matching
For JSON rules,
when.path and when.equals must be provided together. when.equals must be a primitive JSON value: string, number, boolean, or null.
For binary rules, when.path and when.equals are not allowed.
Emit keys
Binary audio response example
Use this when the provider streams raw audio as binary WebSocket frames.JSON base64 audio response example
Use$decode when the provider returns base64-encoded audio inside JSON.
DSL operators
Every DSL operator is a JSON object with one operator key. Operator objects must contain only the operator and its required fields.$var
Reads a supported query variable inside speak.query_params.
Rules:
$varmust be a non-empty string.- The operator object must contain only
$var. $varis not supported in request rules or response rules. Use$paththere.textis not supported as a query variable.
$path
Reads a dot-separated path from the current request scope or JSON response frame.
Rules:
$pathmust be a non-empty string.- The operator object must contain only
$path. - Dot-separated object keys are traversed by key.
- Arrays are traversed by numeric index, such as
chunks.0.audio. - Keys that contain a literal dot are not addressable.
- Missing paths in
when.pathcause the rule not to match. - Missing paths in
send.bodyoremitcause an error. - Response rules can use
$pathonly when the current frame isjson.
$cast
Casts a rendered value to another type.
Rules:
$castmust bestring,number, orboolean.- The operator object must contain only
$castandvalue. valuecan be a literal or another DSL expression.
$frame
Reads the full current binary response frame.
Rules:
$framemust bebinary.- The operator object must contain only
$frame. $frameis useful when the provider streams raw audio as binary WebSocket frames.$frame: "text"and$frame: "json"are not supported for Custom TTS.
$decode
Decodes a base64 string into bytes.
Rules:
$decodemust bebase64.- The operator object must contain only
$decodeandvalue. valuemust resolve to a base64 string.- Use
$decodewhen a JSON response contains base64 audio that should become a playable audio chunk.
Unsupported operators and expressions
The following are not supported in Custom TTS:$frame: "text"$frame: "json"$decodeformats other thanbase64- Text response frames
- Regex, contains, starts-with, greater-than, less-than, and compound conditions
- String interpolation or concatenation
- Fallback values inside expressions
- Dynamic headers
- Dynamic URL path segments
- Environment variable reads
- JavaScript or function calls
Complete setup example
Credential:Runtime behavior
- Rapida builds the final WebSocket URL from
baseUrlandspeak.query_params. - Rapida sends static
headersfrom the credential during the WebSocket handshake. - Rapida opens a connection per active message or context. A new context closes the previous connection.
textpackets open the WebSocket connection if needed.doneandinterruptrequest rules are optional. If no rule exists for that packet, nothing is sent.- On interruption, Rapida sends the optional
interruptrule first, then closes the WebSocket connection. - Provider audio is interpreted as
speak.audio.encodingandspeak.audio.sample_rate, then resampled internally when needed. - If no response rule matches a provider response, the response is ignored.
- If a response emits non-empty
error, Rapida emits a TTS error. - If a response emits audio, Rapida emits a TTS audio packet.
- If a response emits
done: true, Rapida closes the connection and emits a TTS end packet. - If the provider closes the WebSocket normally after synthesis has started, Rapida treats that as completion.
Validation checklist
Before saving or testing, confirm the following:apiCompatibilityiswebsocket_v1or omitted.baseUrlis present and points to the correct WebSocket endpoint.headersinclude required provider authentication.speak.audio.encodingmatches the provider response audio.speak.audio.sample_ratematches the provider response audio.speak.request_rulesis valid JSON and contains at least onetextrule.speak.response_rulesis valid JSON and contains at least one matching audio, done, or error rule.- Binary audio providers use
{ "$frame": "binary" }. - JSON base64 audio providers use
{ "$decode": "base64", "value": ... }. - Providers that require finalization have a
donerequest rule. - Providers that require cancellation have an
interruptrequest rule.
Troubleshooting
Related
Text-to-Speech
Configure standard TTS providers and speech delivery.
Speak configuration
See how TTS fits into assistant voice output settings.
Custom STT
Configure a custom speech-to-text provider with the related DSL pattern.
Assistant API Custom TTS
Review runtime behavior for self-hosted assistant-api deployments.