- Accept streaming audio over WebSocket.
- Accept one HTTP transcription request after the user finishes speaking.
custom-stt
API compatibility: websocket_v1 or http_v1
Custom STT is configured from credentials and assistant voice input 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
Decide whether your STT provider should be configured as
websocket_v1 or http_v1.Use websocket_v1 when the provider opens a persistent WebSocket connection and receives audio chunks while the user is speaking.Use http_v1 when the provider receives one JSON POST per completed speech segment and returns a transcript in the HTTP response.2
Create the Custom STT credential
Open Credentials or Integrations > Models, choose Custom STT, and create a credential with
apiCompatibility, baseUrl, and any required headers.3
Select Custom STT for voice input
Open the assistant or deployment voice settings, go to Voice Input, and select Custom STT as the speech-to-text provider.
4
Set the audio format
Choose the audio encoding and sample rate that your provider expects.Rapida prepares audio before the request rules run. The DSL can then read the configured values from
config.audio.encoding, config.audio.sample_rate, encoding, and sample_rate.5
Write the DSL configuration
Fill
listen.query_params, listen.request_rules, and listen.response_rules.Query parameters build the provider URL. Request rules map Rapida packets to outbound provider frames or HTTP JSON bodies. Response rules map provider responses to transcripts or errors.6
Test with a real call or debugger session
Confirm that the provider receives audio, that transcripts appear in conversation logs, and that partial and final transcripts use the correct
interim value.Credential fields
Create one credential for the external STT provider.
The runtime also accepts snake case credential keys:
api_compatibility and base_url.
Assistant STT arguments
These fields are configured on the assistant or deployment voice input 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.
listen.model and listen.language are optional metadata keys for API-driven or imported configurations. If your provider needs fixed 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 STT option keys, such as
listen.request_rules. The UI may preserve other microphone-level settings under microphone.*, but the custom STT DSL fields are the listen.* keys listed above.Choose WebSocket or HTTP
DSL overview
Custom STT 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
Uselisten.query_params when your provider expects configuration in the URL.
Query variable reference
Query parameter expressions can use$var to read these variables.
Query parameter rules
listen.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 unlesslisten.query_paramsrenders the same key. - A key that starts with
$is treated as an unsupported operator and is rejected.
Request rules
listen.request_rules is an ordered JSON array. Each rule has a when block and a send block.
Request packet reference
Request frame reference
For
websocket_v1, every matching rule for a packet is sent in order. This lets one audio packet produce more than one provider message when the provider requires it.
For http_v1, Rapida evaluates audio request rules after speech ends and uses the first matching rule as the HTTP JSON body.
Request scope
Request rules use$path to read from the request scope. The available scope depends on the packet.
For turn_change:
audio:
interrupt:
Request path reference
Binary audio WebSocket example
Use this when the provider expects raw audio frames.JSON audio WebSocket example
Use this when the provider expects base64 audio inside JSON.Start, audio, and interrupt WebSocket example
Use this when the provider expects a start message, binary audio frames, and a flush message on interruption.HTTP transcription request example
Use this withapiCompatibility: "http_v1" when your provider accepts one JSON POST after each completed speech segment.
For
http_v1, the first matching audio rule must render a json frame. binary and text request frames are valid only for WebSocket STT.Response rules
listen.response_rules is an ordered JSON array. Each provider response is parsed into a json or text frame, then the first matching response rule is evaluated. Later rules are skipped for that response.
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 text rules, when.path is not allowed. If when.equals is omitted, the rule matches any text frame.
Emit keys
JSON partial and final transcript example
Use this when the provider sends structured response events.Nested JSON transcript example
Use numeric path segments to read array indexes.Plain text transcript example
Use this when the provider returns transcript chunks as plain text frames or plain HTTP response text.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 listen.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.
$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
results.0.transcript. - 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 text response frame.
Rules:
$framemust betext.- The operator object must contain only
$frame. $frameis useful when the provider returns the transcript as raw text instead of JSON.$frame: "binary"and$frame: "json"are not supported for Custom STT.
Unsupported operators and expressions
The following are not supported in Custom STT:$decode$frame: "binary"$frame: "json"- 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 WebSocket setup example
Credential:Complete HTTP setup example
Credential:{ "text": "hello", "confidence": "0.94" }:
Runtime behavior
- Rapida builds the final URL from
baseUrlandlisten.query_params. - Rapida sends static
headersfrom the credential. - Rapida prepares audio before evaluating request rules. WebSocket binary audio uses the configured encoding and sample rate; HTTP v1 request scope exposes PCM bytes plus PCM/WAV base64 for the completed speech segment.
websocket_v1opens the WebSocket connection when aturn_changeoraudiopacket needs to be sent.websocket_v1sends all matching request rules for each packet.http_v1buffers user speech audio and sends one HTTP POST when the speech segment ends.http_v1setsContent-Type: application/jsonwhen the credential headers do not already include a content type.- If no response rule matches a provider response, the response is ignored.
- If a response emits non-empty
error, Rapida emits an STT error. - If a response emits non-empty
script, Rapida emits a transcript packet and records the transcript in conversation events.
Validation checklist
Before saving or testing, confirm the following:apiCompatibilityiswebsocket_v1orhttp_v1.baseUrlis present and points to the correct provider endpoint.headersinclude required provider authentication.listen.audio.encodingmatches the provider expectation.listen.audio.sample_ratematches the provider expectation.listen.request_rulesis valid JSON and contains at least oneaudiorule.http_v1usessend.frame: "json"for the first matchingaudiorule.listen.response_rulesis valid JSON and contains at least one matching transcript or error rule.interimistruefor partial transcripts andfalsefor final transcripts.
Troubleshooting
Related
Speech-to-Text
Configure standard STT providers and transcription tuning.
Listen configuration
See how STT fits into assistant voice input settings.
Custom TTS
Configure a custom text-to-speech provider with the related DSL pattern.
Assistant API Custom STT
Review runtime behavior for self-hosted assistant-api deployments.