Skip to main content
Custom Speech-to-Text lets you connect Rapida to a transcription service that is not available as a built-in STT provider. You provide the provider endpoint, authentication headers, audio format, and a JSON DSL that tells Rapida how to send audio and how to read transcripts from provider responses. Use Custom STT when your provider can do one of the following:
  • Accept streaming audio over WebSocket.
  • Accept one HTTP transcription request after the user finishes speaking.
Provider identifier: 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.
Headers are static credential values. The DSL cannot template headers, read environment variables, sign requests, or change the URL path dynamically.

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

For http_v1, turn_change and interrupt request rules do not send provider requests. HTTP STT sends only the buffered audio rule after speech ends.

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

Use listen.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_params must 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 baseUrl are preserved unless listen.query_params renders the same key.
  • A key that starts with $ is treated as an unsupported operator and is rejected.
This configuration:
can produce a provider URL like:

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:
For audio:
For interrupt:

Request path reference

packet.audio.* paths exist only on audio packets. A turn_change or interrupt rule that reads packet.audio.base64 fails validation or runtime evaluation because those packets do not contain audio.

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 with apiCompatibility: "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

If a response rule emits error, Rapida treats the provider response as an STT error. If a rule emits neither a non-empty script nor a non-empty error, the response is ignored.

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:
  • $var must be a non-empty string.
  • The operator object must contain only $var.
  • $var is not supported in request rules or response rules. Use $path there.

$path

Reads a dot-separated path from the current request scope or JSON response frame.
Rules:
  • $path must 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.path cause the rule not to match.
  • Missing paths in send.body or emit cause an error.
  • Response rules can use $path only when the current frame is json.

$cast

Casts a rendered value to another type.
Rules:
  • $cast must be string, number, or boolean.
  • The operator object must contain only $cast and value.
  • value can be a literal or another DSL expression.
Cast behavior:

$frame

Reads the full current text response frame.
Rules:
  • $frame must be text.
  • The operator object must contain only $frame.
  • $frame is 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:
Audio settings:
Query parameters:
Request rules:
Response rules:

Complete HTTP setup example

Credential:
Audio settings:
Request rules:
Response rules for a JSON response like { "text": "hello", "confidence": "0.94" }:

Runtime behavior

  • Rapida builds the final URL from baseUrl and listen.query_params.
  • Rapida sends static headers from 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_v1 opens the WebSocket connection when a turn_change or audio packet needs to be sent.
  • websocket_v1 sends all matching request rules for each packet.
  • http_v1 buffers user speech audio and sends one HTTP POST when the speech segment ends.
  • http_v1 sets Content-Type: application/json when 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:
  • apiCompatibility is websocket_v1 or http_v1.
  • baseUrl is present and points to the correct provider endpoint.
  • headers include required provider authentication.
  • listen.audio.encoding matches the provider expectation.
  • listen.audio.sample_rate matches the provider expectation.
  • listen.request_rules is valid JSON and contains at least one audio rule.
  • http_v1 uses send.frame: "json" for the first matching audio rule.
  • listen.response_rules is valid JSON and contains at least one matching transcript or error rule.
  • interim is true for partial transcripts and false for final transcripts.

Troubleshooting

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.