Skip to main content
Custom STT lets you connect Rapida to a WebSocket or HTTP transcription service without writing a new Go transformer. The UI stores provider credentials and assistant options; assistant-api reads them through the custom-stt transformer and maps audio packets and provider responses with DSL rules. Provider identifier: custom-stt

Where it is configured

1

Create the provider credential

In the Rapida dashboard, open Integrations > Models, choose Custom STT, and create a credential.The backend also accepts snake case keys: api_compatibility and base_url.
2

Select Custom STT on the assistant

Open the assistant voice settings and select Custom STT as the speech-to-text provider.
3

Fill the STT arguments

Set the audio format, query parameters, request rules, and response rules. The argument reference below maps to the UI fields and the transformer option keys.

STT arguments

The UI stores these keys with the microphone. metadata prefix, but the transformer reads the option keys shown below. The current UI exposes the audio and DSL fields; listen.model and listen.language are optional API/import metadata keys that request rules and query parameters can read when present.

Query parameters

Use listen.query_params when your provider expects configuration in the URL. Supported variables:

Request rules

Request rules are evaluated for normalized packets produced by Rapida. Supported outbound frame types are binary, json, and text.
packet.audio.bytes is raw audio bytes for binary frames. Use packet.audio.base64 when the provider expects audio inside a JSON payload.

Binary audio stream

JSON audio payload

HTTP transcription request

Use this shape with apiCompatibility = http_v1 when your provider accepts a JSON POST after each completed speech segment.
For http_v1, the first matching audio rule must use send.frame = json. WebSocket STT can use binary, json, or text outbound frames.

Response rules

Response rules parse provider WebSocket frames or HTTP response bodies into Rapida transcript packets. Supported inbound frame types: Supported emit keys:

STT DSL design

Custom STT uses a JSON-template DSL with three sections: query parameters, request rules, and response rules. The DSL is intentionally small. It does not run scripts, call functions, concatenate strings, perform regex matching, or read environment variables.

STT frame support

Inbound parsing rules:
  • WebSocket message type 2 is treated as binary, but STT response rules do not support binary response frames.
  • Non-binary messages are parsed as JSON when they contain exactly one valid JSON value.
  • Non-JSON messages are treated as text.
  • For STT, JSON string primitives and non-object JSON values are treated as text; JSON response rules operate on JSON objects.

STT operators

Every operator object must contain only that operator and its required field. Unsupported STT operators:
  • $decode is not supported for STT.
  • $frame: "binary" and $frame: "json" are not supported for STT emit rules.

Cast behavior

JSON path behavior

$path uses dot-separated paths.
Objects are traversed by key. Arrays are traversed by numeric index.
Limits:
  • Keys containing a literal dot are not addressable.
  • Request rules can only read from config and packet.
  • Response rules can use $path only with JSON response frames.
  • A missing path in when.path means the rule does not match.
  • A missing path in emit or send.body is an error.

Query parameter rules

listen.query_params must be a flat JSON object. Each value must resolve to a primitive value: string, number, boolean, or null. Nested objects and arrays are rejected unless the object is a DSL expression.
The rendered query parameters are appended to baseUrl. Existing query parameters in baseUrl are preserved unless the same key is rendered by listen.query_params.

Request rule shape

listen.request_rules is an ordered JSON array. For websocket_v1, every matching rule is sent, so one packet can produce multiple WebSocket messages. For http_v1, the first matching audio rule provides the JSON POST body. Body validation depends on send.frame:

STT request scope

The request scope is the data available to $path in request rules.
packet.audio exists only for audio packets.

Response rule shape

listen.response_rules is an ordered JSON array. The first matching rule is evaluated; later rules are skipped for that response. Match behavior:

STT emit keys

Plain text transcript response

Use this for providers that return transcript chunks as raw text frames.

Nested JSON transcript response

Start, audio, and interrupt recipe

Use this pattern when the provider expects a session-start message, binary audio frames, and a flush message on interruption.

Runtime behavior

  • The URL is built from baseUrl and listen.query_params.
  • Headers are copied from the credential and are not templated.
  • Audio is resampled from Rapida’s internal audio format to listen.audio.encoding and listen.audio.sample_rate before request rules are evaluated.
  • For websocket_v1, turn_change and audio packets open the WebSocket connection if needed.
  • For http_v1, Rapida buffers audio while the user is speaking and sends one HTTP POST when the STT end packet arrives.
  • interrupt rules are sent only by the WebSocket transport when a connection is already active.
  • If no response rule matches an inbound frame, the frame is ignored.
  • If a response emits error, Rapida emits an STT error packet.
  • If a response emits non-empty script, Rapida emits a transcript packet and conversation event.

Current STT limits

  • No regex, contains, starts-with, greater-than, or compound match conditions.
  • No string interpolation or concatenation.
  • No fallback values inside expressions.
  • No dynamic headers or dynamic URL path segments.
  • No $decode.
  • No binary response handling for STT.
  • No $frame: "json" selector in emit rules.

Backend mapping

assistant-api resolves custom-stt in api/assistant-api/internal/transformer/transformer.go, then dispatches by credential compatibility: Both STT implementations validate:
  • baseUrl is present in the credential.
  • listen.audio.encoding is not empty.
  • listen.audio.sample_rate is positive.
  • listen.request_rules contains at least one audio packet rule.
  • listen.response_rules contains at least one rule.
http_v1 also requires the first matching audio request rule to emit a json frame because the transport sends an HTTP POST body.

Custom TTS

Configure WebSocket text-to-speech.

STT overview

Transformer interface and supported providers.